Skip to content

Commit e187a7c

Browse files
Change interface for HMAC
This changes the interface for communicating the API key and the signing secret. Specifically it removes them from "authentication options" and moves them to their own parameters instead. This allows using the default pattern for channel options in places that previously did not touch it. This is desired as soon most clients will require the API key and the signing secret to function properly, and we want to keep the changes needed to them minimal. Signed-off-by: Florian Wagner <[email protected]>
1 parent 1eafda5 commit e187a7c

File tree

3 files changed

+22
-44
lines changed

3 files changed

+22
-44
lines changed

src/frequenz/client/base/authentication.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
"""An Interceptor that adds the API key to a gRPC call."""
55

6-
import dataclasses
76
from typing import AsyncIterable, Callable
87

98
from grpc.aio import (
@@ -35,25 +34,17 @@ def _add_auth_header(
3534
client_call_details.metadata["key"] = key
3635

3736

38-
@dataclasses.dataclass(frozen=True)
39-
class AuthenticationOptions:
40-
"""Options for authenticating to the endpoint."""
41-
42-
api_key: str
43-
"""The API key to authenticate with."""
44-
45-
4637
# There is an issue in gRPC which means the type can not be specified correctly here.
4738
class AuthenticationInterceptorUnaryUnary(UnaryUnaryClientInterceptor): # type: ignore[type-arg]
4839
"""An Interceptor that adds HMAC authentication of the metadata fields to a gRPC call."""
4940

50-
def __init__(self, options: AuthenticationOptions):
41+
def __init__(self, api_key: str):
5142
"""Create an instance of the interceptor.
5243
5344
Args:
54-
options: The options for authenticating to the endpoint.
45+
api_key: The API key to send along for the request.
5546
"""
56-
self._key = options.api_key
47+
self._key = api_key
5748

5849
async def intercept_unary_unary(
5950
self,
@@ -83,13 +74,13 @@ async def intercept_unary_unary(
8374
class AuthenticationInterceptorUnaryStream(UnaryStreamClientInterceptor): # type: ignore[type-arg]
8475
"""An Interceptor that adds HMAC authentication of the metadata fields to a gRPC call."""
8576

86-
def __init__(self, options: AuthenticationOptions):
77+
def __init__(self, api_key: str):
8778
"""Create an instance of the interceptor.
8879
8980
Args:
90-
options: The options for authenticating to the endpoint.
81+
api_key: The API key to send along for the request.
9182
"""
92-
self._key = options.api_key
83+
self._key = api_key
9384

9485
async def intercept_unary_stream(
9586
self,

src/frequenz/client/base/channel.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@
2020
from .authentication import (
2121
AuthenticationInterceptorUnaryStream,
2222
AuthenticationInterceptorUnaryUnary,
23-
AuthenticationOptions,
2423
)
2524
from .signing import (
2625
SigningInterceptorUnaryStream,
2726
SigningInterceptorUnaryUnary,
28-
SigningOptions,
2927
)
3028

3129

@@ -85,17 +83,13 @@ class ChannelOptions:
8583
keep_alive: KeepAliveOptions = KeepAliveOptions()
8684
"""HTTP2 keep-alive options for the channel."""
8785

88-
sign: SigningOptions | None = None
89-
"""Signing options for the channel."""
90-
91-
auth: AuthenticationOptions | None = None
92-
"""Authentication options for the channel."""
93-
9486

9587
def parse_grpc_uri(
9688
uri: str,
9789
/,
9890
defaults: ChannelOptions = ChannelOptions(),
91+
key: str | None = None,
92+
sign_secret: str | None = None,
9993
) -> Channel:
10094
"""Create a client channel from a URI.
10195
@@ -133,6 +127,8 @@ def parse_grpc_uri(
133127
uri: The gRPC URI specifying the connection parameters.
134128
defaults: The default options use to create the channel when not specified in
135129
the URI.
130+
key: The API key to use when connecting to the service.
131+
sign_secret: The secret to use when creating message HMAC.
136132
137133
Returns:
138134
A client channel object.
@@ -200,16 +196,16 @@ def parse_grpc_uri(
200196
)
201197

202198
interceptors: list[ClientInterceptor] = []
203-
if defaults.auth is not None:
199+
if key is not None:
204200
interceptors += [
205-
AuthenticationInterceptorUnaryUnary(options=defaults.auth), # type: ignore [list-item]
206-
AuthenticationInterceptorUnaryStream(options=defaults.auth), # type: ignore [list-item]
201+
AuthenticationInterceptorUnaryUnary(api_key=key), # type: ignore [list-item]
202+
AuthenticationInterceptorUnaryStream(api_key=key), # type: ignore [list-item]
207203
]
208204

209-
if defaults.sign is not None:
205+
if sign_secret is not None:
210206
interceptors += [
211-
SigningInterceptorUnaryUnary(options=defaults.sign), # type: ignore [list-item]
212-
SigningInterceptorUnaryStream(options=defaults.sign), # type: ignore [list-item]
207+
SigningInterceptorUnaryUnary(secret=sign_secret), # type: ignore [list-item]
208+
SigningInterceptorUnaryStream(secret=sign_secret), # type: ignore [list-item]
213209
]
214210

215211
ssl = defaults.ssl.enabled if options.ssl is None else options.ssl

src/frequenz/client/base/signing.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
"""An Interceptor that adds HMAC signature of the metadata fields to a gRPC call."""
55

6-
import dataclasses
76
import hmac
87
import logging
98
import secrets
@@ -68,25 +67,17 @@ def _add_hmac(
6867
)
6968

7069

71-
@dataclasses.dataclass(frozen=True)
72-
class SigningOptions:
73-
"""Options for message signing of messages."""
74-
75-
secret: str
76-
"""The secret to sign the message with."""
77-
78-
7970
# There is an issue in gRPC which means the type can not be specified correctly here.
8071
class SigningInterceptorUnaryUnary(UnaryUnaryClientInterceptor): # type: ignore[type-arg]
8172
"""An Interceptor that adds HMAC authentication of the metadata fields to a gRPC call."""
8273

83-
def __init__(self, options: SigningOptions):
74+
def __init__(self, secret: str):
8475
"""Create an instance of the interceptor.
8576
8677
Args:
87-
options: The options for signing the message.
78+
secret: The secret used for signing the message.
8879
"""
89-
self._secret = options.secret.encode()
80+
self._secret = secret.encode()
9081

9182
async def intercept_unary_unary(
9283
self,
@@ -121,13 +112,13 @@ async def intercept_unary_unary(
121112
class SigningInterceptorUnaryStream(UnaryStreamClientInterceptor): # type: ignore[type-arg]
122113
"""An Interceptor that adds HMAC authentication of the metadata fields to a gRPC call."""
123114

124-
def __init__(self, options: SigningOptions):
115+
def __init__(self, secret: str):
125116
"""Create an instance of the interceptor.
126117
127118
Args:
128-
options: The options for signing the message.
119+
secret: The secret used for signing the message.
129120
"""
130-
self._secret = options.secret.encode()
121+
self._secret = secret.encode()
131122

132123
async def intercept_unary_stream(
133124
self,

0 commit comments

Comments
 (0)