hyperpocket 0.0.3__py3-none-any.whl → 0.1.9__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- hyperpocket/auth/README.md +3 -3
- hyperpocket/auth/__init__.py +0 -8
- hyperpocket/auth/gumloop/context.py +13 -0
- hyperpocket/auth/gumloop/token_context.py +15 -0
- hyperpocket/auth/gumloop/token_handler.py +66 -0
- hyperpocket/auth/gumloop/token_schema.py +8 -0
- hyperpocket/auth/linear/token_context.py +1 -1
- hyperpocket/auth/notion/README.md +28 -0
- hyperpocket/auth/notion/context.py +15 -0
- hyperpocket/auth/notion/token_context.py +14 -0
- hyperpocket/auth/notion/token_handler.py +65 -0
- hyperpocket/auth/notion/token_schema.py +10 -0
- hyperpocket/auth/provider.py +8 -5
- hyperpocket/auth/reddit/context.py +15 -0
- hyperpocket/auth/reddit/oauth2_context.py +32 -0
- hyperpocket/auth/reddit/oauth2_handler.py +151 -0
- hyperpocket/auth/reddit/oauth2_schema.py +18 -0
- hyperpocket/auth/slack/token_context.py +1 -1
- hyperpocket/builtin.py +63 -0
- hyperpocket/cli/__main__.py +12 -0
- hyperpocket/cli/auth.py +83 -0
- hyperpocket/cli/codegen/auth/__init__.py +13 -0
- hyperpocket/cli/codegen/auth/auth_context_template.py +16 -0
- hyperpocket/cli/codegen/auth/auth_token_context_template.py +16 -0
- hyperpocket/cli/codegen/auth/auth_token_handler_template.py +69 -0
- hyperpocket/cli/codegen/auth/auth_token_schema_template.py +12 -0
- hyperpocket/cli/codegen/auth/server_auth_template.py +18 -0
- hyperpocket/cli/eject.py +19 -0
- hyperpocket/cli/sync.py +5 -5
- hyperpocket/config/settings.py +14 -12
- hyperpocket/futures/futurestore.py +0 -1
- hyperpocket/pocket_auth.py +25 -5
- hyperpocket/pocket_core.py +264 -0
- hyperpocket/pocket_main.py +127 -174
- hyperpocket/prompts.py +6 -8
- hyperpocket/repository/__init__.py +2 -2
- hyperpocket/repository/lock.py +71 -1
- hyperpocket/repository/lockfile.py +19 -13
- hyperpocket/repository/repository.py +26 -1
- hyperpocket/server/auth/__init__.py +0 -6
- hyperpocket/server/auth/gumloop.py +16 -0
- hyperpocket/server/auth/notion.py +19 -0
- hyperpocket/server/auth/reddit.py +16 -0
- hyperpocket/server/server.py +56 -20
- hyperpocket/server/tool/dto/script.py +15 -2
- hyperpocket/server/tool/wasm.py +20 -8
- hyperpocket/session/README.md +2 -2
- hyperpocket/session/in_memory.py +18 -5
- hyperpocket/session/interface.py +14 -0
- hyperpocket/session/redis.py +29 -5
- hyperpocket/tool/README.md +16 -12
- hyperpocket/tool/__init__.py +4 -3
- hyperpocket/tool/function/README.md +39 -10
- hyperpocket/tool/function/__init__.py +2 -0
- hyperpocket/tool/function/annotation.py +2 -1
- hyperpocket/tool/function/tool.py +108 -29
- hyperpocket/tool/tool.py +100 -28
- hyperpocket/tool/wasm/README.md +27 -5
- hyperpocket/tool/wasm/browser.py +2 -7
- hyperpocket/tool/wasm/script.py +40 -1
- hyperpocket/tool/wasm/templates/python.py +32 -14
- hyperpocket/tool/wasm/tool.py +21 -18
- hyperpocket/tool_like.py +5 -0
- hyperpocket/util/__init__.py +1 -1
- hyperpocket/util/extract_func_param_desc_from_docstring.py +4 -4
- hyperpocket/util/function_to_model.py +5 -2
- hyperpocket/util/json_schema_to_model.py +47 -26
- {hyperpocket-0.0.3.dist-info → hyperpocket-0.1.9.dist-info}/METADATA +107 -88
- hyperpocket-0.1.9.dist-info/RECORD +137 -0
- {hyperpocket-0.0.3.dist-info → hyperpocket-0.1.9.dist-info}/WHEEL +1 -1
- hyperpocket-0.1.9.dist-info/entry_points.txt +2 -0
- hyperpocket/auth/README.KR.md +0 -309
- hyperpocket/auth/slack/tests/test_oauth2_handler.py +0 -32
- hyperpocket/auth/slack/tests/test_token_handler.py +0 -23
- hyperpocket/auth/tests/test_google_oauth2_handler.py +0 -147
- hyperpocket/auth/tests/test_slack_oauth2_handler.py +0 -147
- hyperpocket/auth/tests/test_slack_token_handler.py +0 -66
- hyperpocket/external/__init__.py +0 -7
- hyperpocket/external/github_client.py +0 -19
- hyperpocket/session/README.KR.md +0 -62
- hyperpocket/session/tests/test_in_memory.py +0 -145
- hyperpocket/session/tests/test_redis.py +0 -151
- hyperpocket/tests/test_pocket.py +0 -116
- hyperpocket/tests/test_pocket_auth.py +0 -982
- hyperpocket/tool/README.KR.md +0 -68
- hyperpocket/tool/builtins/__init__.py +0 -0
- hyperpocket/tool/builtins/example/__init__.py +0 -0
- hyperpocket/tool/builtins/example/add_tool.py +0 -18
- hyperpocket/tool/function/README.KR.md +0 -159
- hyperpocket/tool/tests/test_function_tool.py +0 -266
- hyperpocket/tool/wasm/README.KR.md +0 -144
- hyperpocket-0.0.3.dist-info/RECORD +0 -130
- hyperpocket-0.0.3.dist-info/entry_points.txt +0 -3
- /hyperpocket/auth/{slack/tests → gumloop}/__init__.py +0 -0
- /hyperpocket/auth/{tests → notion}/__init__.py +0 -0
- /hyperpocket/{session/tests → auth/reddit}/__init__.py +0 -0
- /hyperpocket/{tests → cli/codegen}/__init__.py +0 -0
@@ -1,147 +0,0 @@
|
|
1
|
-
import uuid
|
2
|
-
from datetime import timezone, datetime
|
3
|
-
from unittest.async_case import IsolatedAsyncioTestCase
|
4
|
-
from unittest.mock import patch
|
5
|
-
from urllib.parse import urlparse, parse_qs
|
6
|
-
|
7
|
-
import httpx
|
8
|
-
|
9
|
-
from hyperpocket.auth import SlackOAuth2AuthContext
|
10
|
-
from hyperpocket.auth.slack.oauth2_handler import SlackOAuth2AuthHandler
|
11
|
-
from hyperpocket.auth.slack.oauth2_schema import SlackOAuth2Request, SlackOAuth2Response
|
12
|
-
from hyperpocket.config import config
|
13
|
-
from hyperpocket.config.auth import SlackAuthConfig
|
14
|
-
from hyperpocket.futures import FutureStore
|
15
|
-
|
16
|
-
|
17
|
-
class TestSlackOAuth2AuthHandler(IsolatedAsyncioTestCase):
|
18
|
-
|
19
|
-
async def asyncSetUp(self):
|
20
|
-
config.auth.slack = SlackAuthConfig(
|
21
|
-
client_id="test-client-id",
|
22
|
-
client_secret="test-client-secret",
|
23
|
-
)
|
24
|
-
|
25
|
-
self.handler = SlackOAuth2AuthHandler()
|
26
|
-
self.auth_req = SlackOAuth2Request(
|
27
|
-
auth_scopes=["channels:history", "im:history", "mpim:history", "groups:history", "reactions:read"],
|
28
|
-
client_id="test-client-id",
|
29
|
-
client_secret="test-client-secret",
|
30
|
-
)
|
31
|
-
|
32
|
-
async def test_make_auth_url(self):
|
33
|
-
future_uid = str(uuid.uuid4())
|
34
|
-
|
35
|
-
auth_url = self.handler._make_auth_url(
|
36
|
-
req=self.auth_req,
|
37
|
-
redirect_uri="http://test-redirect-uri.com",
|
38
|
-
state=future_uid
|
39
|
-
)
|
40
|
-
parsed = urlparse(auth_url)
|
41
|
-
query_params = parse_qs(parsed.query)
|
42
|
-
base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
|
43
|
-
|
44
|
-
# then
|
45
|
-
self.assertEqual(base_url, SlackOAuth2AuthHandler._SLACK_OAUTH_URL)
|
46
|
-
self.assertEqual(query_params["state"][0], future_uid)
|
47
|
-
self.assertEqual(query_params["redirect_uri"][0], "http://test-redirect-uri.com")
|
48
|
-
self.assertEqual(query_params["client_id"][0], "test-client-id")
|
49
|
-
self.assertEqual(query_params["user_scope"][0],
|
50
|
-
"channels:history,im:history,mpim:history,groups:history,reactions:read")
|
51
|
-
|
52
|
-
async def test_prepare(self):
|
53
|
-
future_uid = str(uuid.uuid4())
|
54
|
-
|
55
|
-
# when
|
56
|
-
prepare: str = self.handler.prepare(
|
57
|
-
auth_req=self.auth_req,
|
58
|
-
thread_id="test-prepare-thread-id",
|
59
|
-
profile="test-prepare-profile",
|
60
|
-
future_uid=future_uid,
|
61
|
-
)
|
62
|
-
auth_url = prepare.removeprefix("User needs to authenticate using the following URL:").strip()
|
63
|
-
future_data = FutureStore.get_future( uid=future_uid)
|
64
|
-
|
65
|
-
# then
|
66
|
-
self.assertTrue(auth_url.startswith(SlackOAuth2AuthHandler._SLACK_OAUTH_URL))
|
67
|
-
self.assertIsNotNone(future_data)
|
68
|
-
self.assertEqual(future_data.data["thread_id"], "test-prepare-thread-id")
|
69
|
-
self.assertEqual(future_data.data["profile"], "test-prepare-profile")
|
70
|
-
self.assertFalse(future_data.future.done())
|
71
|
-
|
72
|
-
async def test_authenticate(self):
|
73
|
-
# given
|
74
|
-
future_uid = str(uuid.uuid4())
|
75
|
-
mock_response = httpx.Response(
|
76
|
-
status_code=200,
|
77
|
-
json={
|
78
|
-
"ok": True,
|
79
|
-
"authed_user": {
|
80
|
-
"id": "test-user",
|
81
|
-
"access_token": "test-token"
|
82
|
-
}
|
83
|
-
|
84
|
-
}
|
85
|
-
)
|
86
|
-
|
87
|
-
# when
|
88
|
-
self.handler.prepare(
|
89
|
-
auth_req=self.auth_req,
|
90
|
-
thread_id="test-thread-id",
|
91
|
-
profile="test-profile",
|
92
|
-
future_uid=future_uid
|
93
|
-
)
|
94
|
-
future_data = FutureStore.get_future( uid=future_uid)
|
95
|
-
future_data.future.set_result("test-code")
|
96
|
-
|
97
|
-
with patch("httpx.AsyncClient.post", return_value=mock_response):
|
98
|
-
response: SlackOAuth2AuthContext = await self.handler.authenticate(
|
99
|
-
auth_req=self.auth_req,
|
100
|
-
future_uid=future_uid
|
101
|
-
)
|
102
|
-
|
103
|
-
self.assertIsInstance(response, SlackOAuth2AuthContext)
|
104
|
-
self.assertEqual(response.access_token, "test-token")
|
105
|
-
|
106
|
-
async def test_refresh(self):
|
107
|
-
# given
|
108
|
-
# https://api.slack.com/authentication/rotation
|
109
|
-
mock_response = httpx.Response(
|
110
|
-
status_code=200,
|
111
|
-
json={
|
112
|
-
"ok": True,
|
113
|
-
"access_token": "new-access-token",
|
114
|
-
"refresh_token": "new-refresh-token",
|
115
|
-
"expires_in": 3600,
|
116
|
-
}
|
117
|
-
)
|
118
|
-
|
119
|
-
response = SlackOAuth2Response(
|
120
|
-
**{
|
121
|
-
"ok": True,
|
122
|
-
"authed_user": {
|
123
|
-
"id": "test",
|
124
|
-
"access_token": "access-token",
|
125
|
-
"refresh_token": "refresh-token",
|
126
|
-
"expires_in": 3600,
|
127
|
-
}
|
128
|
-
}
|
129
|
-
)
|
130
|
-
context = SlackOAuth2AuthContext.from_slack_oauth2_response(response)
|
131
|
-
|
132
|
-
# when
|
133
|
-
with patch("httpx.AsyncClient.post", return_value=mock_response):
|
134
|
-
new_context: SlackOAuth2AuthContext = await self.handler.refresh(
|
135
|
-
auth_req=self.auth_req,
|
136
|
-
context=context
|
137
|
-
)
|
138
|
-
|
139
|
-
time_diff = (new_context.expires_at - datetime.now(tz=timezone.utc))
|
140
|
-
|
141
|
-
# then
|
142
|
-
self.assertIsInstance(new_context, SlackOAuth2AuthContext)
|
143
|
-
self.assertEqual(context.access_token, "access-token")
|
144
|
-
self.assertEqual(context.refresh_token, "refresh-token")
|
145
|
-
self.assertEqual(new_context.access_token, "new-access-token")
|
146
|
-
self.assertEqual(new_context.refresh_token, "new-refresh-token")
|
147
|
-
self.assertTrue(time_diff.total_seconds() > 3500)
|
@@ -1,66 +0,0 @@
|
|
1
|
-
from unittest.async_case import IsolatedAsyncioTestCase
|
2
|
-
from urllib.parse import urlparse, parse_qs
|
3
|
-
|
4
|
-
from hyperpocket.auth import SlackTokenAuthContext
|
5
|
-
from hyperpocket.auth.slack.token_handler import SlackTokenAuthHandler
|
6
|
-
from hyperpocket.auth.slack.token_schema import SlackTokenRequest
|
7
|
-
from hyperpocket.futures import FutureStore
|
8
|
-
|
9
|
-
|
10
|
-
class TestSlackTokenAuthHandler(IsolatedAsyncioTestCase):
|
11
|
-
|
12
|
-
async def asyncSetUp(self):
|
13
|
-
self.handler: SlackTokenAuthHandler = SlackTokenAuthHandler()
|
14
|
-
self.auth_req = SlackTokenRequest()
|
15
|
-
|
16
|
-
async def test_make_auth_url(self):
|
17
|
-
auth_url = self.handler._make_auth_url(
|
18
|
-
req=self.auth_req,
|
19
|
-
redirect_uri="http://test-redirect-uri.com",
|
20
|
-
state="test-future-id"
|
21
|
-
)
|
22
|
-
parsed = urlparse(auth_url)
|
23
|
-
query_params = parse_qs(parsed.query)
|
24
|
-
base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
|
25
|
-
|
26
|
-
# then
|
27
|
-
self.assertEqual(base_url, self.handler._TOKEN_URL)
|
28
|
-
self.assertEqual(query_params["state"][0], "test-future-id")
|
29
|
-
self.assertEqual(query_params["redirect_uri"][0], "http://test-redirect-uri.com")
|
30
|
-
|
31
|
-
async def test_prepare(self):
|
32
|
-
# when
|
33
|
-
prepare: str = self.handler.prepare(
|
34
|
-
auth_req=self.auth_req,
|
35
|
-
thread_id="test-prepare-thread-id",
|
36
|
-
profile="test-prepare-profile",
|
37
|
-
future_uid="test-prepare-future-uid",
|
38
|
-
)
|
39
|
-
auth_url = prepare.removeprefix("User needs to authenticate using the following URL:").strip()
|
40
|
-
future_data = FutureStore.get_future( uid="test-prepare-future-uid")
|
41
|
-
|
42
|
-
# then
|
43
|
-
self.assertTrue(auth_url.startswith(self.handler._TOKEN_URL))
|
44
|
-
self.assertIsNotNone(future_data)
|
45
|
-
self.assertEqual(future_data.data["thread_id"], "test-prepare-thread-id")
|
46
|
-
self.assertEqual(future_data.data["profile"], "test-prepare-profile")
|
47
|
-
self.assertFalse(future_data.future.done())
|
48
|
-
|
49
|
-
async def test_authenticate(self):
|
50
|
-
self.handler.prepare(
|
51
|
-
auth_req=self.auth_req,
|
52
|
-
thread_id="test-thread-id",
|
53
|
-
profile="test-profile",
|
54
|
-
future_uid="test-future-uid"
|
55
|
-
)
|
56
|
-
future_data = FutureStore.get_future( uid="test-future-uid")
|
57
|
-
future_data.future.set_result("test-token")
|
58
|
-
|
59
|
-
response: SlackTokenAuthContext = await self.handler.authenticate(
|
60
|
-
auth_req=self.auth_req,
|
61
|
-
future_uid="test-future-uid"
|
62
|
-
)
|
63
|
-
|
64
|
-
self.assertIsInstance(response, SlackTokenAuthContext)
|
65
|
-
self.assertEqual(response.access_token, "test-token")
|
66
|
-
self.assertIsNone(response.expires_at)
|
hyperpocket/external/__init__.py
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
from github import Auth, Github, GithubIntegration
|
2
|
-
|
3
|
-
from hyperpocket.config import config
|
4
|
-
|
5
|
-
_github = None
|
6
|
-
|
7
|
-
|
8
|
-
def github_instance() -> Github:
|
9
|
-
global _github
|
10
|
-
if _github is None:
|
11
|
-
if config.git.github.github_token:
|
12
|
-
_github = Github(auth=Auth.Token(config.git.github.github_token))
|
13
|
-
elif config.git.github.app_id:
|
14
|
-
auth = Auth.AppAuth(config.git.github.app_id, config.git.github.app_private_key)
|
15
|
-
gi = GithubIntegration(auth=auth)
|
16
|
-
_github = gi.get_github_for_installation(config.git.github.app_installation_id)
|
17
|
-
else:
|
18
|
-
_github = Github()
|
19
|
-
return _github
|
hyperpocket/session/README.KR.md
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# Session Storage
|
2
|
-
|
3
|
-
유저의 authentication(auth) session을 저장하기 위한 storage
|
4
|
-
|
5
|
-
## Current supported session storage
|
6
|
-
|
7
|
-
- [x] InMemory
|
8
|
-
- [x] Redis
|
9
|
-
- [ ] Postgres
|
10
|
-
- [ ] Mysql
|
11
|
-
- [ ] Mongodb
|
12
|
-
|
13
|
-
## SessionKey
|
14
|
-
|
15
|
-
세션 키는 유저의 인증 정보를 식별하기 위한 유니크 키이다.
|
16
|
-
|
17
|
-
일반적으로 세션 키는 다음 세 가지 요소로 식별될 수 있다.
|
18
|
-
|
19
|
-
- auth provider
|
20
|
-
- profile
|
21
|
-
- thread_id
|
22
|
-
|
23
|
-
하나의 auth provider에서는 하나의 session만 가질 수 있다.
|
24
|
-
|
25
|
-
- 예를 들어 slack token으로 이미 인증한 사용자가 oauth로 인증하려 하면 이전 세션은 사라지게 된다.
|
26
|
-
|
27
|
-
- profile은 pocket에서 지원하는 개념으로 하나의 thread_id에 여러 profile이 존재할 수 있다.
|
28
|
-
|
29
|
-
- profile을 이용해 한 사용자는 여러 persona를 갖고 작업을 수행하도록 할 수 있다.
|
30
|
-
- e.g., A group의 슬랙 메세지를 읽어 B group으로 요약해서 전달
|
31
|
-
|
32
|
-
## BaseSessionValue
|
33
|
-
|
34
|
-
```python
|
35
|
-
class BaseSessionValue(BaseModel):
|
36
|
-
auth_provider_name: str
|
37
|
-
auth_context: Optional[AuthContext] = None
|
38
|
-
scoped: bool
|
39
|
-
auth_scopes: Optional[Set[str]] = None
|
40
|
-
auth_resolve_uid: Optional[str] = None
|
41
|
-
```
|
42
|
-
|
43
|
-
기본적으로 Session에는 다음 정보들을 갖고 있다.
|
44
|
-
|
45
|
-
- auth_provider_name : 현재 세션을 인증한 auth provider name
|
46
|
-
- auth_context : 실제 세션 내용이 들어있는 auth context
|
47
|
-
- scoped : 현재 세션이 scoped session인지 여부
|
48
|
-
- auth_scopes : 현재 세션의 auth scopes. scoped session의 경우에만 존재
|
49
|
-
- auth_resolve_uid : 유저가 auth 인증을 완료했는지를 비동기적으로 확인하기 위한 uid
|
50
|
-
|
51
|
-
## SessionStorageInterface
|
52
|
-
|
53
|
-
TBU
|
54
|
-
|
55
|
-
## How To Implement
|
56
|
-
|
57
|
-
1. `pocket/config/session.py` 내에 새로운 SessionType Enum 추가
|
58
|
-
2. `pocket/config/session.py` 내에 새로운 SessionConfig 추가
|
59
|
-
3. SessionStorageInterface 구현
|
60
|
-
- session storage가 초기화될 때 위에서 정의한 SessionConfig를 입력으로 받아야 한다.
|
61
|
-
|
62
|
-
|
@@ -1,145 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
from hyperpocket.auth import AuthProvider, SlackTokenAuthContext
|
4
|
-
from hyperpocket.config.session import SessionConfigInMemory
|
5
|
-
from hyperpocket.session.in_memory import InMemorySessionStorage, InMemorySessionValue
|
6
|
-
|
7
|
-
|
8
|
-
class TestInMemorySessionStorage(unittest.TestCase):
|
9
|
-
storage: InMemorySessionStorage
|
10
|
-
context: SlackTokenAuthContext
|
11
|
-
|
12
|
-
def setUp(self):
|
13
|
-
self.storage = InMemorySessionStorage(SessionConfigInMemory())
|
14
|
-
self.auth_context = SlackTokenAuthContext(
|
15
|
-
access_token="test",
|
16
|
-
description="test-description",
|
17
|
-
expires_at=None,
|
18
|
-
detail=None,
|
19
|
-
)
|
20
|
-
|
21
|
-
def tearDown(self):
|
22
|
-
del self.storage
|
23
|
-
del self.auth_context
|
24
|
-
|
25
|
-
def test_make_session_key(self):
|
26
|
-
key = self.storage._make_session_key(
|
27
|
-
auth_provider=AuthProvider.SLACK,
|
28
|
-
thread_id="default_thread_id",
|
29
|
-
profile="default_profile"
|
30
|
-
)
|
31
|
-
|
32
|
-
self.assertEqual(key, "SLACK__default_thread_id__default_profile")
|
33
|
-
|
34
|
-
def test_make_session(self):
|
35
|
-
session = self.storage._make_session(
|
36
|
-
auth_provider_name=AuthProvider.SLACK.name,
|
37
|
-
auth_scopes=["scope1", "scope2"],
|
38
|
-
auth_context=self.auth_context,
|
39
|
-
auth_resolve_uid="test-resolve-uid",
|
40
|
-
is_auth_scope_universal=True
|
41
|
-
)
|
42
|
-
|
43
|
-
# then
|
44
|
-
self.assertIsInstance(session, InMemorySessionValue)
|
45
|
-
self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
|
46
|
-
self.assertEqual(session.auth_context.access_token, "test")
|
47
|
-
self.assertEqual(session.auth_context.description, "test-description")
|
48
|
-
|
49
|
-
def test_set(self):
|
50
|
-
session = self.storage.set(
|
51
|
-
auth_provider=AuthProvider.SLACK,
|
52
|
-
thread_id="default_thread_id",
|
53
|
-
profile="default_profile",
|
54
|
-
auth_scopes=["scope1", "scope2"],
|
55
|
-
auth_resolve_uid="test-resolve-uid",
|
56
|
-
auth_context=self.auth_context,
|
57
|
-
is_auth_scope_universal=True
|
58
|
-
)
|
59
|
-
|
60
|
-
self.assertIsInstance(session, InMemorySessionValue)
|
61
|
-
self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
|
62
|
-
self.assertEqual(session.auth_context.access_token, self.auth_context.access_token)
|
63
|
-
self.assertEqual(session.auth_context.description, self.auth_context.description)
|
64
|
-
|
65
|
-
def test_get_existing_data(self):
|
66
|
-
# given
|
67
|
-
self.storage.set(
|
68
|
-
auth_provider=AuthProvider.SLACK,
|
69
|
-
thread_id="default_thread_id",
|
70
|
-
profile="default_profile",
|
71
|
-
auth_scopes=["scope1", "scope2"],
|
72
|
-
auth_resolve_uid="test-resolve-uid",
|
73
|
-
auth_context=self.auth_context,
|
74
|
-
is_auth_scope_universal=True
|
75
|
-
)
|
76
|
-
|
77
|
-
# when
|
78
|
-
session = self.storage.get(
|
79
|
-
auth_provider=AuthProvider.SLACK,
|
80
|
-
thread_id="default_thread_id",
|
81
|
-
profile="default_profile",
|
82
|
-
)
|
83
|
-
|
84
|
-
# then
|
85
|
-
self.assertIsInstance(session, InMemorySessionValue)
|
86
|
-
self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
|
87
|
-
self.assertEqual(session.auth_context.access_token, "test")
|
88
|
-
self.assertEqual(session.auth_context.description, "test-description")
|
89
|
-
|
90
|
-
def test_get_not_existing_data(self):
|
91
|
-
# when
|
92
|
-
session = self.storage.get(
|
93
|
-
auth_provider=AuthProvider.SLACK,
|
94
|
-
thread_id="default_thread_id",
|
95
|
-
profile="default_profile",
|
96
|
-
)
|
97
|
-
|
98
|
-
# then
|
99
|
-
self.assertIsNone(session)
|
100
|
-
|
101
|
-
def test_delete_existing_data(self):
|
102
|
-
# given
|
103
|
-
self.storage.set(
|
104
|
-
auth_provider=AuthProvider.SLACK,
|
105
|
-
thread_id="default_thread_id",
|
106
|
-
profile="default_profile",
|
107
|
-
auth_scopes=["scope1", "scope2"],
|
108
|
-
auth_resolve_uid="test-resolve-uid",
|
109
|
-
auth_context=self.auth_context,
|
110
|
-
is_auth_scope_universal=True
|
111
|
-
)
|
112
|
-
|
113
|
-
# when
|
114
|
-
before_session = self.storage.get(
|
115
|
-
auth_provider=AuthProvider.SLACK,
|
116
|
-
thread_id="default_thread_id",
|
117
|
-
profile="default_profile",
|
118
|
-
)
|
119
|
-
|
120
|
-
deleted = self.storage.delete(
|
121
|
-
auth_provider=AuthProvider.SLACK,
|
122
|
-
thread_id="default_thread_id",
|
123
|
-
profile="default_profile",
|
124
|
-
)
|
125
|
-
|
126
|
-
after_session = self.storage.get(
|
127
|
-
auth_provider=AuthProvider.SLACK,
|
128
|
-
thread_id="default_thread_id",
|
129
|
-
profile="default_profile",
|
130
|
-
)
|
131
|
-
|
132
|
-
# then
|
133
|
-
self.assertTrue(deleted)
|
134
|
-
self.assertIsNotNone(before_session)
|
135
|
-
self.assertIsNone(after_session)
|
136
|
-
|
137
|
-
def test_delete_not_existing_data(self):
|
138
|
-
deleted = self.storage.delete(
|
139
|
-
auth_provider=AuthProvider.SLACK,
|
140
|
-
thread_id="default_thread_id",
|
141
|
-
profile="default_profile",
|
142
|
-
)
|
143
|
-
|
144
|
-
# then
|
145
|
-
self.assertFalse(deleted)
|
@@ -1,151 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
from hyperpocket.auth import AuthProvider, SlackTokenAuthContext
|
4
|
-
from hyperpocket.config.session import SessionConfigRedis
|
5
|
-
from hyperpocket.session.in_memory import InMemorySessionValue
|
6
|
-
from hyperpocket.session.redis import RedisSessionStorage, RedisSessionValue
|
7
|
-
|
8
|
-
|
9
|
-
class TestRedisSessionStorage(unittest.TestCase):
|
10
|
-
storage: RedisSessionStorage
|
11
|
-
context: SlackTokenAuthContext
|
12
|
-
|
13
|
-
def setUp(self):
|
14
|
-
self.storage = RedisSessionStorage(SessionConfigRedis(
|
15
|
-
host="localhost",
|
16
|
-
port=6379,
|
17
|
-
db="9"
|
18
|
-
))
|
19
|
-
self.storage.client.flushdb()
|
20
|
-
|
21
|
-
self.auth_context = SlackTokenAuthContext(
|
22
|
-
access_token="test",
|
23
|
-
description="test-description",
|
24
|
-
expires_at=None,
|
25
|
-
detail=None,
|
26
|
-
)
|
27
|
-
|
28
|
-
def tearDown(self):
|
29
|
-
self.storage.client.flushdb()
|
30
|
-
|
31
|
-
def test_make_session_key(self):
|
32
|
-
key = self.storage._make_session_key(
|
33
|
-
auth_provider=AuthProvider.SLACK,
|
34
|
-
thread_id="default_thread_id",
|
35
|
-
profile="default_profile"
|
36
|
-
)
|
37
|
-
|
38
|
-
self.assertEqual(key, "SLACK__default_thread_id__default_profile")
|
39
|
-
|
40
|
-
def test_make_session(self):
|
41
|
-
session = self.storage._make_session(
|
42
|
-
auth_provider_name=AuthProvider.SLACK.name,
|
43
|
-
auth_scopes=["scope1", "scope2"],
|
44
|
-
auth_context=self.auth_context,
|
45
|
-
auth_resolve_uid="test-resolve-uid",
|
46
|
-
is_auth_scope_universal=True
|
47
|
-
)
|
48
|
-
|
49
|
-
# then
|
50
|
-
self.assertIsInstance(session, RedisSessionValue)
|
51
|
-
self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
|
52
|
-
self.assertEqual(session.auth_context.access_token, "test")
|
53
|
-
self.assertEqual(session.auth_context.description, "test-description")
|
54
|
-
|
55
|
-
def test_set(self):
|
56
|
-
session = self.storage.set(
|
57
|
-
auth_provider=AuthProvider.SLACK,
|
58
|
-
thread_id="default_thread_id",
|
59
|
-
profile="default_profile",
|
60
|
-
auth_scopes=["scope1", "scope2"],
|
61
|
-
auth_resolve_uid="test-resolve-uid",
|
62
|
-
auth_context=self.auth_context,
|
63
|
-
is_auth_scope_universal=True
|
64
|
-
)
|
65
|
-
|
66
|
-
self.assertIsInstance(session, InMemorySessionValue)
|
67
|
-
self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
|
68
|
-
self.assertEqual(session.auth_context.access_token, self.auth_context.access_token)
|
69
|
-
self.assertEqual(session.auth_context.description, self.auth_context.description)
|
70
|
-
|
71
|
-
def test_get_existing_data(self):
|
72
|
-
# given
|
73
|
-
self.storage.set(
|
74
|
-
auth_provider=AuthProvider.SLACK,
|
75
|
-
thread_id="default_thread_id",
|
76
|
-
profile="default_profile",
|
77
|
-
auth_scopes=["scope1", "scope2"],
|
78
|
-
auth_resolve_uid="test-resolve-uid",
|
79
|
-
auth_context=self.auth_context,
|
80
|
-
is_auth_scope_universal=True
|
81
|
-
)
|
82
|
-
|
83
|
-
# when
|
84
|
-
session = self.storage.get(
|
85
|
-
auth_provider=AuthProvider.SLACK,
|
86
|
-
thread_id="default_thread_id",
|
87
|
-
profile="default_profile",
|
88
|
-
)
|
89
|
-
|
90
|
-
# then
|
91
|
-
self.assertIsInstance(session, InMemorySessionValue)
|
92
|
-
self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
|
93
|
-
self.assertEqual(session.auth_context.access_token, "test")
|
94
|
-
self.assertEqual(session.auth_context.description, "test-description")
|
95
|
-
|
96
|
-
def test_get_not_existing_data(self):
|
97
|
-
# when
|
98
|
-
session = self.storage.get(
|
99
|
-
auth_provider=AuthProvider.SLACK,
|
100
|
-
thread_id="default_thread_id",
|
101
|
-
profile="default_profile",
|
102
|
-
)
|
103
|
-
|
104
|
-
# then
|
105
|
-
self.assertIsNone(session)
|
106
|
-
|
107
|
-
def test_delete_existing_data(self):
|
108
|
-
# given
|
109
|
-
self.storage.set(
|
110
|
-
auth_provider=AuthProvider.SLACK,
|
111
|
-
thread_id="default_thread_id",
|
112
|
-
profile="default_profile",
|
113
|
-
auth_scopes=["scope1", "scope2"],
|
114
|
-
auth_resolve_uid="test-resolve-uid",
|
115
|
-
auth_context=self.auth_context,
|
116
|
-
is_auth_scope_universal=True
|
117
|
-
)
|
118
|
-
|
119
|
-
# when
|
120
|
-
before_session = self.storage.get(
|
121
|
-
auth_provider=AuthProvider.SLACK,
|
122
|
-
thread_id="default_thread_id",
|
123
|
-
profile="default_profile",
|
124
|
-
)
|
125
|
-
|
126
|
-
deleted = self.storage.delete(
|
127
|
-
auth_provider=AuthProvider.SLACK,
|
128
|
-
thread_id="default_thread_id",
|
129
|
-
profile="default_profile",
|
130
|
-
)
|
131
|
-
|
132
|
-
after_session = self.storage.get(
|
133
|
-
auth_provider=AuthProvider.SLACK,
|
134
|
-
thread_id="default_thread_id",
|
135
|
-
profile="default_profile",
|
136
|
-
)
|
137
|
-
|
138
|
-
# then
|
139
|
-
self.assertTrue(deleted)
|
140
|
-
self.assertIsNotNone(before_session)
|
141
|
-
self.assertIsNone(after_session)
|
142
|
-
|
143
|
-
def test_delete_not_existing_data(self):
|
144
|
-
deleted = self.storage.delete(
|
145
|
-
auth_provider=AuthProvider.SLACK,
|
146
|
-
thread_id="default_thread_id",
|
147
|
-
profile="default_profile",
|
148
|
-
)
|
149
|
-
|
150
|
-
# then
|
151
|
-
self.assertFalse(deleted)
|