Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb13971d

Browse files
nejchmax-wittig
authored andcommitted
feat(api): support access token rotate API
1 parent57749d4 commitb13971d

12 files changed

+193
-36
lines changed

‎docs/gl_objects/group_access_tokens.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,12 @@ Revoke a group access token::
3737
gl.groups.get(1).access_tokens.delete(42)
3838
# or
3939
access_token.delete()
40+
41+
Rotate a group access token and retrieve its new value::
42+
43+
token = group.access_tokens.get(42, lazy=True)
44+
token.rotate()
45+
print(token.token)
46+
# or directly using a token ID
47+
new_token = group.access_tokens.rotate(42)
48+
print(new_token.token)

‎docs/gl_objects/personal_access_tokens.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ Revoke the personal access token currently used::
5252

5353
gl.personal_access_tokens.delete("self")
5454

55+
Rotate a personal access token and retrieve its new value::
56+
57+
token = gl.personal_access_tokens.get(42, lazy=True)
58+
token.rotate()
59+
print(token.token)
60+
# or directly using a token ID
61+
new_token = gl.personal_access_tokens.rotate(42)
62+
print(new_token.token)
63+
5564
Create a personal access token for a user (admin only)::
5665

5766
user = gl.users.get(25, lazy=True)

‎docs/gl_objects/project_access_tokens.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,17 @@ Create project access token::
3232

3333
access_token = gl.projects.get(1).access_tokens.create({"name": "test", "scopes": ["api"], "expires_at": "2023-06-06"})
3434

35-
Revoke a project accesstokens::
35+
Revoke a project accesstoken::
3636

3737
gl.projects.get(1).access_tokens.delete(42)
3838
# or
3939
access_token.delete()
40+
41+
Rotate a project access token and retrieve its new value::
42+
43+
token = project.access_tokens.get(42, lazy=True)
44+
token.rotate()
45+
print(token.token)
46+
# or directly using a token ID
47+
new_token = project.access_tokens.rotate(42)
48+
print(new_token.token)

‎gitlab/exceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ class GitlabRevertError(GitlabOperationError):
288288
pass
289289

290290

291+
classGitlabRotateError(GitlabOperationError):
292+
pass
293+
294+
291295
classGitlabLicenseError(GitlabOperationError):
292296
pass
293297

@@ -397,6 +401,7 @@ def wrapped_f(*args: Any, **kwargs: Any) -> Any:
397401
"GitlabRestoreError",
398402
"GitlabRetryError",
399403
"GitlabRevertError",
404+
"GitlabRotateError",
400405
"GitlabSearchError",
401406
"GitlabSetError",
402407
"GitlabStopError",

‎gitlab/mixins.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,65 @@ def download(
653653
)
654654

655655

656+
classRotateMixin(_RestManagerBase):
657+
_computed_path:Optional[str]
658+
_from_parent_attrs:Dict[str,Any]
659+
_obj_cls:Optional[Type[base.RESTObject]]
660+
_parent:Optional[base.RESTObject]
661+
_parent_attrs:Dict[str,Any]
662+
_path:Optional[str]
663+
gitlab:gitlab.Gitlab
664+
665+
@exc.on_http_error(exc.GitlabRotateError)
666+
defrotate(
667+
self,id:Union[str,int],expires_at:Optional[str]=None,**kwargs:Any
668+
)->Dict[str,Any]:
669+
"""Rotate an access token.
670+
671+
Args:
672+
id: ID of the token to rotate
673+
**kwargs: Extra options to send to the server (e.g. sudo)
674+
675+
Raises:
676+
GitlabAuthenticationError: If authentication is not correct
677+
GitlabRotateError: If the server cannot perform the request
678+
"""
679+
path=f"{self.path}/{utils.EncodedId(id)}/rotate"
680+
data:Dict[str,Any]= {}
681+
ifexpires_atisnotNone:
682+
data= {"expires_at":expires_at}
683+
684+
server_data=self.gitlab.http_post(path,post_data=data,**kwargs)
685+
ifTYPE_CHECKING:
686+
assertnotisinstance(server_data,requests.Response)
687+
returnserver_data
688+
689+
690+
classObjectRotateMixin(_RestObjectBase):
691+
_id_attr:Optional[str]
692+
_attrs:Dict[str,Any]
693+
_module:ModuleType
694+
_parent_attrs:Dict[str,Any]
695+
_updated_attrs:Dict[str,Any]
696+
manager:base.RESTManager
697+
698+
defrotate(self,**kwargs:Any)->None:
699+
"""Rotate the current access token object.
700+
701+
Args:
702+
**kwargs: Extra options to send to the server (e.g. sudo)
703+
704+
Raises:
705+
GitlabAuthenticationError: If authentication is not correct
706+
GitlabRotateError: If the server cannot perform the request
707+
"""
708+
ifTYPE_CHECKING:
709+
assertisinstance(self.manager,RotateMixin)
710+
assertself.encoded_idisnotNone
711+
server_data=self.manager.rotate(self.encoded_id,**kwargs)
712+
self._update_attrs(server_data)
713+
714+
656715
classSubscribableMixin(_RestObjectBase):
657716
_id_attr:Optional[str]
658717
_attrs:Dict[str,Any]

‎gitlab/v4/objects/group_access_tokens.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
fromtypingimportAny,cast,Union
22

33
fromgitlab.baseimportRESTManager,RESTObject
4-
fromgitlab.mixinsimportCreateMixin,DeleteMixin,ObjectDeleteMixin,RetrieveMixin
4+
fromgitlab.mixinsimport (
5+
CreateMixin,
6+
DeleteMixin,
7+
ObjectDeleteMixin,
8+
ObjectRotateMixin,
9+
RetrieveMixin,
10+
RotateMixin,
11+
)
512
fromgitlab.typesimportArrayAttribute,RequiredOptional
613

714
__all__= [
@@ -10,11 +17,13 @@
1017
]
1118

1219

13-
classGroupAccessToken(ObjectDeleteMixin,RESTObject):
20+
classGroupAccessToken(ObjectDeleteMixin,ObjectRotateMixin,RESTObject):
1421
pass
1522

1623

17-
classGroupAccessTokenManager(CreateMixin,DeleteMixin,RetrieveMixin,RESTManager):
24+
classGroupAccessTokenManager(
25+
CreateMixin,DeleteMixin,RetrieveMixin,RotateMixin,RESTManager
26+
):
1827
_path="/groups/{group_id}/access_tokens"
1928
_obj_cls=GroupAccessToken
2029
_from_parent_attrs= {"group_id":"id"}

‎gitlab/v4/objects/personal_access_tokens.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
fromtypingimportAny,cast,Union
22

33
fromgitlab.baseimportRESTManager,RESTObject
4-
fromgitlab.mixinsimportCreateMixin,DeleteMixin,ObjectDeleteMixin,RetrieveMixin
4+
fromgitlab.mixinsimport (
5+
CreateMixin,
6+
DeleteMixin,
7+
ObjectDeleteMixin,
8+
ObjectRotateMixin,
9+
RetrieveMixin,
10+
RotateMixin,
11+
)
512
fromgitlab.typesimportArrayAttribute,RequiredOptional
613

714
__all__= [
@@ -12,11 +19,11 @@
1219
]
1320

1421

15-
classPersonalAccessToken(ObjectDeleteMixin,RESTObject):
22+
classPersonalAccessToken(ObjectDeleteMixin,ObjectRotateMixin,RESTObject):
1623
pass
1724

1825

19-
classPersonalAccessTokenManager(DeleteMixin,RetrieveMixin,RESTManager):
26+
classPersonalAccessTokenManager(DeleteMixin,RetrieveMixin,RotateMixin,RESTManager):
2027
_path="/personal_access_tokens"
2128
_obj_cls=PersonalAccessToken
2229
_list_filters= ("user_id",)

‎gitlab/v4/objects/project_access_tokens.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
fromtypingimportAny,cast,Union
22

33
fromgitlab.baseimportRESTManager,RESTObject
4-
fromgitlab.mixinsimportCreateMixin,DeleteMixin,ObjectDeleteMixin,RetrieveMixin
4+
fromgitlab.mixinsimport (
5+
CreateMixin,
6+
DeleteMixin,
7+
ObjectDeleteMixin,
8+
ObjectRotateMixin,
9+
RetrieveMixin,
10+
RotateMixin,
11+
)
512
fromgitlab.typesimportArrayAttribute,RequiredOptional
613

714
__all__= [
@@ -10,11 +17,13 @@
1017
]
1118

1219

13-
classProjectAccessToken(ObjectDeleteMixin,RESTObject):
20+
classProjectAccessToken(ObjectDeleteMixin,ObjectRotateMixin,RESTObject):
1421
pass
1522

1623

17-
classProjectAccessTokenManager(CreateMixin,DeleteMixin,RetrieveMixin,RESTManager):
24+
classProjectAccessTokenManager(
25+
CreateMixin,DeleteMixin,RetrieveMixin,RotateMixin,RESTManager
26+
):
1827
_path="/projects/{project_id}/access_tokens"
1928
_obj_cls=ProjectAccessToken
2029
_from_parent_attrs= {"project_id":"id"}

‎tests/unit/objects/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def token_content():
3232
"active":True,
3333
"created_at":"2021-01-20T22:11:48.151Z",
3434
"revoked":False,
35+
"token":"s3cr3t",
3536
}
3637

3738

‎tests/unit/objects/test_group_access_tokens.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,12 @@ def resp_get_group_access_token(token_content):
3535

3636

3737
@pytest.fixture
38-
defresp_create_group_access_token():
39-
content= {
40-
"user_id":141,
41-
"scopes": ["api"],
42-
"name":"token",
43-
"expires_at":"2021-01-31",
44-
"id":42,
45-
"active":True,
46-
"created_at":"2021-01-20T22:11:48.151Z",
47-
"revoked":False,
48-
}
49-
38+
defresp_create_group_access_token(token_content):
5039
withresponses.RequestsMock(assert_all_requests_are_fired=False)asrsps:
5140
rsps.add(
5241
method=responses.POST,
5342
url="http://localhost/api/v4/groups/1/access_tokens",
54-
json=content,
43+
json=token_content,
5544
content_type="application/json",
5645
status=200,
5746
)
@@ -89,6 +78,19 @@ def resp_revoke_group_access_token():
8978
yieldrsps
9079

9180

81+
@pytest.fixture
82+
defresp_rotate_group_access_token(token_content):
83+
withresponses.RequestsMock()asrsps:
84+
rsps.add(
85+
method=responses.POST,
86+
url="http://localhost/api/v4/groups/1/access_tokens/1/rotate",
87+
json=token_content,
88+
content_type="application/json",
89+
status=200,
90+
)
91+
yieldrsps
92+
93+
9294
deftest_list_group_access_tokens(gl,resp_list_group_access_token):
9395
access_tokens=gl.groups.get(1,lazy=True).access_tokens.list()
9496
assertlen(access_tokens)==1
@@ -118,3 +120,10 @@ def test_revoke_group_access_token(
118120
gl.groups.get(1,lazy=True).access_tokens.delete(42)
119121
access_token=gl.groups.get(1,lazy=True).access_tokens.list()[0]
120122
access_token.delete()
123+
124+
125+
deftest_rotate_group_access_token(group,resp_rotate_group_access_token):
126+
access_token=group.access_tokens.get(1,lazy=True)
127+
access_token.rotate()
128+
assertisinstance(access_token,GroupAccessToken)
129+
assertaccess_token.token=="s3cr3t"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp