Skip to content

Commit

Permalink
Merge pull request #5 from tokopedia:f_fixing_test
Browse files Browse the repository at this point in the history
feat(sdk): Adding public key verification on check status
  • Loading branch information
dafaath authored Nov 14, 2024
2 parents 24e6e5e + 9e084b4 commit 3f24790
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 152 deletions.
30 changes: 13 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
.with_is_debug(True)
)

Expand All @@ -75,11 +74,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
# Override SAT Base URL
.with_sat_base_url("https://b2b.tokopedia.com/api")
)
Expand Down Expand Up @@ -113,11 +111,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
# Override SAT Base URL
.with_sat_base_url("https://b2b.tokopedia.com/api")
)
Expand Down Expand Up @@ -155,11 +152,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
# Override SAT Base URL
.with_sat_base_url("https://b2b.tokopedia.com/api")
)
Expand Down Expand Up @@ -201,11 +197,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
# Override SAT Base URL
.with_sat_base_url("https://b2b.tokopedia.com/api")
)
Expand Down Expand Up @@ -254,11 +249,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
# Override SAT Base URL
.with_sat_base_url("https://b2b.tokopedia.com/api")
)
Expand All @@ -275,11 +269,10 @@ config = (
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)
# Below is optional parameter
.with_timeout(10)
# Public key is optional, used only for callback signature verification
.with_public_key("SAT_PUBLIC_KEY")
# Override SAT Base URL
.with_sat_base_url("https://b2b.tokopedia.com/api")
)
Expand All @@ -303,7 +296,8 @@ config = SATClientConfig(
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE_KEY", # required
).with_public_key("SAT_PUBLIC_KEY")
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)

sat_client = SATClient(config)

Expand Down Expand Up @@ -354,7 +348,8 @@ config = SATClientConfig(
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE", # required
).with_public_key("SAT_PUBLIC_KEY")
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)

sat_client = SATClient(config)

Expand Down Expand Up @@ -387,7 +382,8 @@ config = SATClientConfig(
client_id="YOUR_CLIENT_ID", # required
client_secret="YOUR_CLIENT_SECRET", # required
private_key="YOUR_PRIVATE", # required
).with_public_key("SAT_PUBLIC_KEY")
sat_public_key="SAT_PUBLIC_KEY", # required !IMPORTANT: This is SAT public key, NOT your public key
)

try:
sat_client = SATClient(config)
Expand Down
25 changes: 18 additions & 7 deletions py_sat/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class SATClientConfig:
client_id: str
client_secret: str
private_key: str
sat_public_key: str

# Optional
public_key: Optional[str]
padding_type: SignatureType
is_debug: bool
sat_base_url: str
Expand All @@ -49,6 +49,7 @@ def __init__(
client_id: str,
client_secret: str,
private_key: str,
sat_public_key: str,
):
if not client_id or not isinstance(client_id, str):
raise InvalidInputException("Client ID are required and must be a string")
Expand All @@ -61,9 +62,13 @@ def __init__(
if not private_key or not isinstance(private_key, str):
raise InvalidInputException("Private key is required and must be a string")

if not sat_public_key or not isinstance(sat_public_key, str):
raise InvalidInputException("Public key is required and must be a string")

self.client_id = client_id
self.client_secret = client_secret
self.private_key = private_key
self.sat_public_key = sat_public_key

self._set_default_value()

Expand All @@ -73,7 +78,6 @@ def _set_default_value(self):
logger.setLevel(logging.DEBUG)
self.logger = logger

self.public_key = None
self.padding_type = SignatureType.PSS
self.is_debug = False
self.sat_base_url = PLAYGROUND_SAT_BASE_URL
Expand All @@ -84,10 +88,6 @@ def with_logger(self, logger: logging.Logger):
self.logger = logger
return self

def with_public_key(self, public_key: str):
self.public_key = public_key
return self

def with_padding_type(self, padding_type: SignatureType):
self.padding_type = padding_type
return self
Expand Down Expand Up @@ -122,7 +122,7 @@ class SATClient:
def __init__(self, config: SATClientConfig):
self._config = config
self.signature = Signature(
config.private_key, config.public_key, config.padding_type
config.private_key, config.sat_public_key, config.padding_type
)
self._logger = config.logger
self._http_client = HTTPClient(
Expand Down Expand Up @@ -235,7 +235,18 @@ def check_status(self, request_id: str) -> Union[OrderDetail, ErrorResponse]:
response = self._http_client.send_request(http_req)
response.raise_for_status()

signature = response.headers.get("signature")
if not signature:
raise UnauthenticatedException(
"Signature is not present in the header, please check the request"
)

valid = self.signature.verify(response.text, signature)
if not valid:
raise UnauthenticatedException("Signature is not valid")

json_response = response.json()

data = parse_json_api_response(json_response)

return OrderDetail.from_dict(data).with_raw_response(response)
Expand Down
4 changes: 2 additions & 2 deletions py_sat/signature/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ class Signature:
def __init__(
self,
private_key_str: Optional[str],
public_key_str: Optional[str],
sat_public_key_str: Optional[str],
padding_type: SignatureType,
):
if not padding_type:
raise InvalidInputException("Padding type is required")

self._private_key = self._parse_rsa_private_key_from_pem_str(private_key_str)
self._public_key = self._parse_public_key(public_key_str)
self._public_key = self._parse_public_key(sat_public_key_str)
self._algorithm = self.__decide_padding_algorithm(padding_type)

def verify(self, msg: str, signature: str) -> bool:
Expand Down
Loading

0 comments on commit 3f24790

Please sign in to comment.