Skip to content

Commit 492da4e

Browse files
committed
Added and update all token handlers for user api
1 parent 8a40d0c commit 492da4e

6 files changed

Lines changed: 129 additions & 57 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,4 @@ dmypy.json
137137
# Custom
138138
.secrets/
139139
.bugout/
140+
test/

bugout/app.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any, Dict, List, Optional, Tuple
1+
from typing import Any, Dict, List, Optional, Tuple, Union
2+
import uuid
23

34
from . import data
45
from . import calls
@@ -7,6 +8,12 @@
78
from .user import User
89

910

11+
class InvalidParameters(ValueError):
12+
"""
13+
Raised when provided invalid parameters.
14+
"""
15+
16+
1017
class Bugout:
1118
def __init__(
1219
self, brood_api_url: Optional[str] = None, spire_api_url: Optional[str] = None
@@ -27,13 +34,17 @@ def spire_url(self):
2734
return self.spire_api_url
2835

2936
def brood_ping(self) -> Dict[str, str]:
37+
if self.brood_api_url is None:
38+
raise InvalidParameters("Brood API url should be provided")
3039
return calls.ping(self.brood_api_url)
3140

3241
def spire_ping(self) -> Dict[str, str]:
42+
if self.spire_api_url is None:
43+
raise InvalidParameters("Spire API url should be provided")
3344
return calls.ping(self.spire_api_url)
3445

3546
# User handlers
36-
def get_user(self, token: str) -> data.BugoutUser:
47+
def get_user(self, token: uuid.UUID) -> data.BugoutUser:
3748
return self.user.get_user(token)
3849

3950
def create_user(
@@ -47,24 +58,41 @@ def create_user(
4758
username, email, password, autogenerated_token=autogenerated_token
4859
)
4960

61+
# Token handlers
5062
def create_token(self, username: str, password: str) -> data.BugoutToken:
5163
return self.user.create_token(username, password)
5264

53-
def revoke_token(self, token: str) -> data.BugoutToken:
65+
def revoke_token(self, token: uuid.UUID) -> data.BugoutToken:
5466
return self.user.revoke_token(token)
5567

68+
def revoke_token_by_id(self, token: uuid.UUID) -> data.BugoutToken:
69+
return self.user.revoke_token_by_id(token)
70+
5671
def update_token(
5772
self,
58-
token: str,
59-
token_type: Optional[str] = None,
73+
token: uuid.UUID,
74+
token_type: Optional[data.TokenType] = None,
6075
token_note: Optional[str] = None,
6176
) -> data.BugoutToken:
6277
return self.user.update_token(token, token_type, token_note)
6378

79+
def get_token_types(self, token: uuid.UUID) -> List[str]:
80+
return self.user.get_token_types(token)
81+
82+
def get_user_tokens(
83+
self,
84+
token: uuid.UUID,
85+
active: Optional[bool] = None,
86+
token_type: Optional[data.TokenType] = None,
87+
):
88+
return self.user.get_user_tokens(token, active, token_type)
89+
6490
# Group handlers
65-
def get_group(self, group_id: str, token: str) -> data.BugoutGroup:
91+
def get_group(self, group_id: uuid.UUID, token: uuid.UUID) -> data.BugoutGroup:
6692
return self.group.get_group(group_id, token)
6793

6894
# Journal handlers
69-
def get_journal(self, journal_id: str, token: str) -> data.BugoutJournal:
95+
def get_journal(
96+
self, journal_id: uuid.UUID, token: uuid.UUID
97+
) -> data.BugoutJournal:
7098
return self.journal.get_journal(journal_id, token)

bugout/data.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Any, Dict, List, Optional, Tuple
44
import uuid
55

6-
from pydantic import BaseModel
6+
from pydantic import BaseModel, Field
77

88

99
@unique
@@ -22,7 +22,7 @@ class TokenType(Enum):
2222

2323

2424
class BugoutUser(BaseModel):
25-
id: uuid.UUID
25+
id: uuid.UUID = Field(alias="user_id")
2626
username: str
2727
email: str
2828
normalized_email: str
@@ -32,6 +32,22 @@ class BugoutUser(BaseModel):
3232
updated_at: datetime
3333

3434

35+
class BugoutToken(BaseModel):
36+
id: uuid.UUID
37+
user_id: uuid.UUID
38+
active: bool
39+
token_type: Optional[str]
40+
note: Optional[str]
41+
created_at: datetime
42+
updated_at: datetime
43+
44+
45+
class BugoutUserTokens(BaseModel):
46+
user_id: uuid.UUID
47+
username: str
48+
tokens: List[BugoutToken] = Field(alias="token")
49+
50+
3551
class BugoutGroup(BaseModel):
3652
id: uuid.UUID
3753
group_name: Optional[str]
@@ -45,9 +61,3 @@ class BugoutJournal(BaseModel):
4561
name: str
4662
created_at: datetime
4763
updated_at: datetime
48-
49-
50-
class BugoutToken(BaseModel):
51-
id: uuid.UUID
52-
token_type: Optional[str]
53-
token_note: Optional[str]

bugout/group.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from typing import Any, Dict, List, Optional, Tuple
3+
import uuid
34

45
from .calls import make_request, InvalidUrlSpec
56
from .data import BugoutGroup, Method
@@ -28,7 +29,7 @@ def _call(self, method: Method, path: str, **kwargs):
2829
result = make_request(method=method, url=url, **kwargs)
2930
return result
3031

31-
def get_group(self, group_id: str, token: str) -> BugoutGroup:
32+
def get_group(self, group_id: uuid.UUID, token: uuid.UUID) -> BugoutGroup:
3233
get_group_path = f"groups/{group_id}"
3334
headers = {
3435
"Authorization": f"Bearer {token}",

bugout/journal.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from typing import Any, Dict, List, Optional, Tuple
3+
import uuid
34

45
from .calls import make_request, InvalidUrlSpec
56
from .data import BugoutJournal, Method
@@ -28,7 +29,7 @@ def _call(self, method: Method, path: str, **kwargs):
2829
result = make_request(method=method, url=url, **kwargs)
2930
return result
3031

31-
def get_journal(self, journal_id: str, token: str) -> BugoutJournal:
32+
def get_journal(self, journal_id: uuid.UUID, token: uuid.UUID) -> BugoutJournal:
3233
get_group_path = f"journals/{journal_id}"
3334
headers = {
3435
"Authorization": f"Bearer {token}",

bugout/user.py

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import json
12
import logging
2-
from typing import Any, Dict, List, Optional, Tuple
3+
from typing import Any, Dict, List, Optional, Tuple, Union
4+
import uuid
35

46
from .calls import make_request, InvalidUrlSpec
5-
from .data import BugoutUser, BugoutToken, Method, TokenType
7+
from .data import Method, TokenType, BugoutUser, BugoutToken, BugoutUserTokens
68

79
logger = logging.getLogger(__name__)
810

@@ -35,33 +37,14 @@ def _call(self, method: Method, path: str, **kwargs):
3537
result = make_request(method=method, url=url, **kwargs)
3638
return result
3739

38-
def _user_model_converter(self, user_object: Dict[str, Any]) -> BugoutUser:
39-
return BugoutUser(
40-
id=user_object.get("user_id"),
41-
username=user_object.get("username"),
42-
email=user_object.get("email"),
43-
normalized_email=user_object.get("normalized_email"),
44-
verified=user_object.get("verified"),
45-
autogenerated=user_object.get("autogenerated"),
46-
created_at=user_object.get("created_at"),
47-
updated_at=user_object.get("updated_at"),
48-
)
49-
50-
def get_user(self, token: str) -> Dict[str, Any]:
51-
get_user_path = "user"
52-
headers = {
53-
"Authorization": f"Bearer {token}",
54-
}
55-
result = self._call(method=Method.get, path=get_user_path, headers=headers)
56-
return self._user_model_converter(result)
57-
40+
# User module
5841
def create_user(
5942
self,
6043
username: str,
6144
email: str,
6245
password: str,
6346
autogenerated_token: Optional[str] = None,
64-
) -> Dict[str, Any]:
47+
) -> BugoutUser:
6548
create_user_path = "user"
6649
data = {
6750
"username": username,
@@ -76,50 +59,98 @@ def create_user(
7659
result = self._call(
7760
method=Method.post, path=create_user_path, headers=headers, data=data
7861
)
79-
return self._user_model_converter(result)
62+
return BugoutUser(**result)
8063

64+
def get_user(self, token: uuid.UUID) -> BugoutUser:
65+
get_user_path = "user"
66+
headers = {
67+
"Authorization": f"Bearer {token}",
68+
}
69+
result = self._call(method=Method.get, path=get_user_path, headers=headers)
70+
return BugoutUser(**result)
71+
72+
# Token module
8173
def create_token(self, username: str, password: str) -> BugoutToken:
8274
create_token_path = "token"
8375
data = {
8476
"username": username,
8577
"password": password,
8678
}
8779
result = self._call(method=Method.post, path=create_token_path, data=data)
88-
return BugoutToken(
89-
id=result.get("access_token"),
90-
token_type=result.get("token_type"),
91-
)
80+
return BugoutToken(**result)
9281

93-
def revoke_token(self, token: str) -> BugoutToken:
94-
create_token_path = "token"
82+
def revoke_token(self, token: uuid.UUID) -> BugoutToken:
83+
revoke_token_path = "token"
9584
headers = {
9685
"Authorization": f"Bearer {token}",
9786
}
9887
result = self._call(
99-
method=Method.delete, path=create_token_path, headers=headers
88+
method=Method.delete, path=revoke_token_path, headers=headers
10089
)
101-
return BugoutToken(id=result)
90+
return result
91+
92+
def revoke_token_by_id(self, token: uuid.UUID) -> BugoutToken:
93+
revoke_token_path = f"token/{token}"
94+
result = self._call(method=Method.delete, path=revoke_token_path)
95+
return result
10296

10397
def update_token(
10498
self,
105-
token: str,
106-
token_type: Optional[str] = None,
99+
token: uuid.UUID,
100+
token_type: Optional[TokenType] = None,
107101
token_note: Optional[str] = None,
108102
) -> BugoutToken:
109-
create_token_path = "token"
103+
update_token_path = "token"
110104

111-
data = {"access_token": token}
105+
data: Dict[str, Any] = {"access_token": token}
112106
if token_type is None and token_note is None:
113107
raise TokenInvalidParameters(
114108
"In order to update token, at least one of token_type, or token_note must be specified"
115109
)
116-
if token_type not in TokenType.__members__:
117-
raise TokenInvalidParameters("Incorrect token type provided")
110+
if token_type is not None and token_type not in TokenType.__members__:
111+
raise TokenInvalidParameters(
112+
"Incorrect token type provided, check types at get_token_types()"
113+
)
118114

119115
if token_type is not None:
120116
data.update({"token_type": token_type})
121117
if token_note is not None:
122118
data.update({"token_note": token_note})
123119

124-
result = self._call(method=Method.put, path=create_token_path, data=data)
125-
return BugoutToken(id=result, token_type=token_type, token_note=token_note)
120+
result = self._call(method=Method.put, path=update_token_path, data=data)
121+
return BugoutToken(**result)
122+
123+
def get_token_types(self, token: uuid.UUID) -> List[str]:
124+
get_token_types_path = "token/types"
125+
headers = {
126+
"Authorization": f"Bearer {token}",
127+
}
128+
result = self._call(
129+
method=Method.get, path=get_token_types_path, headers=headers
130+
)
131+
return result
132+
133+
def get_user_tokens(
134+
self,
135+
token: uuid.UUID,
136+
active: Optional[bool] = None,
137+
token_type: Optional[TokenType] = None,
138+
):
139+
get_user_tokens_path = "tokens"
140+
headers = {
141+
"Authorization": f"Bearer {token}",
142+
}
143+
if token_type is not None and token_type not in TokenType.__members__:
144+
raise TokenInvalidParameters(
145+
"Incorrect token type provided, check types at get_token_types()"
146+
)
147+
if active is not None and token_type is None:
148+
get_user_tokens_path += f"?active={active}"
149+
elif active is None and token_type is not None:
150+
get_user_tokens_path += f"?token_type={token_type}"
151+
elif active is not None and token_type is not None:
152+
get_user_tokens_path += f"?active={active}&token_type={token_type}"
153+
result = self._call(
154+
method=Method.get, path=get_user_tokens_path, headers=headers
155+
)
156+
return BugoutUserTokens(**result)

0 commit comments

Comments
 (0)