1 from __future__ import annotations
2
3 import json
4 from dataclasses import dataclass
5 from enum import Enum
6 from importlib.metadata import PackageNotFoundError, version
7 from typing import Any, Dict
8
9 from ._native import NativeSdkError
10 from ._native import login_with_client as _login_with_client
11 from ._native import logout_with_client as _logout_with_client
12 from ._native import me_with_client as _me_with_client
13 from ._native import remove_with_client as _remove_with_client
14 from ._native import signup_with_client as _signup_with_client
15
16
17 class Environment(str, Enum):
18 DEV = "dev"
19 PRODUCTION = "production"
20
21
22 class SdkError(Exception):
23 def __init__(self, error_code: int, error_name: str, message: str) -> None:
24 super().__init__(message)
25 self.error_code = error_code
26 self.error_name = error_name
27 self.message = message
28
29
30 @dataclass(frozen=True)
31 class AuthClient:
32 env: Environment
33 app_id: str
34 app_secret: str
35
36 def signup(self, email: str, password: str) -> Dict[str, Any]:
37 return signup_with_client(self.env, self.app_id, self.app_secret, email, password)
38
39 def login(self, email: str, password: str) -> Dict[str, Any]:
40 return login_with_client(self.env, self.app_id, self.app_secret, email, password)
41
42 def logout(self, access_token: str) -> None:
43 logout_with_client(self.env, self.app_id, self.app_secret, access_token)
44
45 def me(self, access_token: str) -> Dict[str, Any]:
46 return me_with_client(self.env, self.app_id, self.app_secret, access_token)
47
48 def remove(self, access_token: str) -> None:
49 remove_with_client(self.env, self.app_id, self.app_secret, access_token)
50
51
52 def signup_with_client(
53 env: Environment | str,
54 app_id: str,
55 app_secret: str,
56 email: str,
57 password: str,
58 ) -> Dict[str, Any]:
59 return _run(_signup_with_client, env, app_id, app_secret, email, password)
60
61
62 def login_with_client(
63 env: Environment | str,
64 app_id: str,
65 app_secret: str,
66 email: str,
67 password: str,
68 ) -> Dict[str, Any]:
69 return _run(_login_with_client, env, app_id, app_secret, email, password)
70
71
72 def logout_with_client(
73 env: Environment | str,
74 app_id: str,
75 app_secret: str,
76 access_token: str,
77 ) -> None:
78 _run(_logout_with_client, env, app_id, app_secret, access_token)
79
80
81 def me_with_client(
82 env: Environment | str,
83 app_id: str,
84 app_secret: str,
85 access_token: str,
86 ) -> Dict[str, Any]:
87 return _run(_me_with_client, env, app_id, app_secret, access_token)
88
89
90 def remove_with_client(
91 env: Environment | str,
92 app_id: str,
93 app_secret: str,
94 access_token: str,
95 ) -> None:
96 _run(_remove_with_client, env, app_id, app_secret, access_token)
97
98
99 def _run(func: Any, env: Environment | str, *args: str) -> Any:
100 try:
101 return func(_normalize_env(env), *args)
102 except NativeSdkError as exc:
103 raise _sdk_error_from_native(exc) from exc
104
105
106 def _normalize_env(env: Environment | str) -> str:
107 if isinstance(env, Environment):
108 return env.value
109 return Environment(env).value
110
111
112 def _sdk_error_from_native(exc: NativeSdkError) -> SdkError:
113 try:
114 payload = json.loads(str(exc))
115 except json.JSONDecodeError:
116 return SdkError(0, "Unknown", str(exc))
117
118 return SdkError(
119 int(payload.get("error_code", 0)),
120 str(payload.get("error_name", "Unknown")),
121 str(payload.get("message", str(exc))),
122 )
123
124
125 try:
126 __version__ = version("smbcloud-sdk-auth")
127 except PackageNotFoundError:
128 __version__ = "0.0.0"
129
130
131 __all__ = [
132 "AuthClient",
133 "Environment",
134 "SdkError",
135 "__version__",
136 "login_with_client",
137 "logout_with_client",
138 "me_with_client",
139 "remove_with_client",
140 "signup_with_client",
141 ]