|
2 | 2 | import os |
3 | 3 | import ssl |
4 | 4 |
|
5 | | -import grpc |
6 | 5 | import jwt |
7 | 6 | import requests |
8 | 7 | from aiohttp import hdrs, web |
9 | 8 | from google.protobuf import json_format |
10 | 9 | from jwt.algorithms import RSAAlgorithm |
11 | | -from temporalio.api.cloud.cloudservice.v1 import request_response_pb2, service_pb2_grpc |
12 | | -from temporalio.api.common.v1 import Payload, Payloads |
| 10 | +from temporalio.api.cloud.cloudservice.v1 import GetUsersRequest |
| 11 | +from temporalio.api.common.v1 import Payloads |
| 12 | +from temporalio.client import CloudOperationsClient |
13 | 13 |
|
14 | 14 | from encryption_jwt.codec import EncryptionCodec |
15 | 15 |
|
16 | 16 | AUTHORIZED_ACCOUNT_ACCESS_ROLES = ["owner", "admin"] |
17 | 17 | AUTHORIZED_NAMESPACE_ACCESS_ROLES = ["read", "write", "admin"] |
18 | 18 |
|
| 19 | +TEMPORAL_CLIENT_CLOUD_API_VERSION = "2024-05-13-00" |
| 20 | + |
19 | 21 | temporal_ops_address = "saas-api.tmprl.cloud:443" |
20 | 22 | if os.environ.get("TEMPORAL_OPS_ADDRESS"): |
21 | 23 | temporal_ops_address = os.environ.get("TEMPORAL_OPS_ADDRESS") |
@@ -45,44 +47,32 @@ async def cors_options(req: web.Request) -> web.Response: |
45 | 47 |
|
46 | 48 | return resp |
47 | 49 |
|
48 | | - def decryption_authorized(email: str, namespace: str) -> bool: |
49 | | - credentials = grpc.composite_channel_credentials( |
50 | | - grpc.ssl_channel_credentials(), |
51 | | - grpc.access_token_call_credentials(os.environ.get("TEMPORAL_API_KEY")), |
| 50 | + async def decryption_authorized(email: str, namespace: str) -> bool: |
| 51 | + client = await CloudOperationsClient.connect( |
| 52 | + api_key=os.environ.get("TEMPORAL_API_KEY"), |
| 53 | + version=TEMPORAL_CLIENT_CLOUD_API_VERSION, |
52 | 54 | ) |
53 | 55 |
|
54 | | - with grpc.secure_channel(temporal_ops_address, credentials) as channel: |
55 | | - client = service_pb2_grpc.CloudServiceStub(channel) |
56 | | - request = request_response_pb2.GetUsersRequest() |
57 | | - |
58 | | - response = client.GetUsers( |
59 | | - request, |
60 | | - metadata=( |
61 | | - ( |
62 | | - "temporal-cloud-api-version", |
63 | | - os.environ.get("TEMPORAL_OPS_API_VERSION"), |
64 | | - ), |
65 | | - ), |
66 | | - ) |
| 56 | + response = await client.cloud_service.get_users( |
| 57 | + GetUsersRequest(namespace=namespace) |
| 58 | + ) |
67 | 59 |
|
68 | | - for user in response.users: |
69 | | - if user.spec.email.lower() == email.lower(): |
70 | | - if ( |
71 | | - user.spec.access.account_access.role |
72 | | - in AUTHORIZED_ACCOUNT_ACCESS_ROLES |
73 | | - ): |
74 | | - return True |
75 | | - else: |
76 | | - if namespace in user.spec.access.namespace_accesses: |
77 | | - if ( |
78 | | - user.spec.access.namespace_accesses[ |
79 | | - namespace |
80 | | - ].permission |
81 | | - in AUTHORIZED_NAMESPACE_ACCESS_ROLES |
82 | | - ): |
83 | | - return True |
84 | | - |
85 | | - return False |
| 60 | + for user in response.users: |
| 61 | + if user.spec.email.lower() == email.lower(): |
| 62 | + if ( |
| 63 | + user.spec.access.account_access.role |
| 64 | + in AUTHORIZED_ACCOUNT_ACCESS_ROLES |
| 65 | + ): |
| 66 | + return True |
| 67 | + else: |
| 68 | + if namespace in user.spec.access.namespace_accesses: |
| 69 | + if ( |
| 70 | + user.spec.access.namespace_accesses[namespace].permission |
| 71 | + in AUTHORIZED_NAMESPACE_ACCESS_ROLES |
| 72 | + ): |
| 73 | + return True |
| 74 | + |
| 75 | + return False |
86 | 76 |
|
87 | 77 | def make_handler(fn: str): |
88 | 78 | async def handler(req: web.Request): |
@@ -122,7 +112,7 @@ async def handler(req: web.Request): |
122 | 112 | ) |
123 | 113 |
|
124 | 114 | # Use the email to determine if the user is authorized to decrypt the payload |
125 | | - authorized = decryption_authorized( |
| 115 | + authorized = await decryption_authorized( |
126 | 116 | decoded["https://saas-api.tmprl.cloud/user/email"], namespace |
127 | 117 | ) |
128 | 118 |
|
|
0 commit comments