Skip to content

Commit

Permalink
feat(projects): add project access token api
Browse files Browse the repository at this point in the history
  • Loading branch information
max-wittig committed Feb 24, 2021
1 parent f6fd995 commit 1becef0
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
34 changes: 34 additions & 0 deletions docs/gl_objects/project_access_tokens.rst
@@ -0,0 +1,34 @@
#####################
Project Access Tokens
#####################

Get a list of project access tokens

References
----------

* v4 API:

+ :class:`gitlab.v4.objects.ProjectAccessToken`
+ :class:`gitlab.v4.objects.ProjectAccessTokenManager`
+ :attr:`gitlab.Gitlab.project_access_tokens`

* GitLab API: https://docs.gitlab.com/ee/api/resource_access_tokens.html

Examples
--------

List project access tokens::

access_tokens = gl.projects.get(1, lazy=True).access_tokens.list()
print(access_tokens[0].name)

Create project access token::

access_token = gl.projects.get(1).access_tokens.create({"name": "test", "scopes": ["api"]})

Revoke a project access tokens::

gl.projects.get(1).access_tokens.delete(42)
# or
access_token.delete()
139 changes: 139 additions & 0 deletions gitlab/tests/objects/test_project_access_tokens.py
@@ -0,0 +1,139 @@
"""
GitLab API: https://docs.gitlab.com/ee/api/resource_access_tokens.html
"""

import pytest
import responses


@pytest.fixture
def resp_list_project_access_token():
content = [
{
"user_id": 141,
"scopes": ["api"],
"name": "token",
"expires_at": "2021-01-31",
"id": 42,
"active": True,
"created_at": "2021-01-20T22:11:48.151Z",
"revoked": False,
}
]

with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/access_tokens",
json=content,
content_type="application/json",
status=200,
)
yield rsps


@pytest.fixture
def resp_create_project_access_token():
content = {
"user_id": 141,
"scopes": ["api"],
"name": "token",
"expires_at": "2021-01-31",
"id": 42,
"active": True,
"created_at": "2021-01-20T22:11:48.151Z",
"revoked": False,
}

with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
rsps.add(
method=responses.POST,
url="http://localhost/api/v4/projects/1/access_tokens",
json=content,
content_type="application/json",
status=200,
)
yield rsps


@pytest.fixture
def resp_list_project_access_token():
content = [
{
"user_id": 141,
"scopes": ["api"],
"name": "token",
"expires_at": "2021-01-31",
"id": 42,
"active": True,
"created_at": "2021-01-20T22:11:48.151Z",
"revoked": False,
}
]

with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/access_tokens",
json=content,
content_type="application/json",
status=200,
)
yield rsps


@pytest.fixture
def resp_revoke_project_access_token():
content = [
{
"user_id": 141,
"scopes": ["api"],
"name": "token",
"expires_at": "2021-01-31",
"id": 42,
"active": True,
"created_at": "2021-01-20T22:11:48.151Z",
"revoked": False,
}
]

with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
rsps.add(
method=responses.DELETE,
url="http://localhost/api/v4/projects/1/access_tokens/42",
json=content,
content_type="application/json",
status=204,
)
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/access_tokens",
json=content,
content_type="application/json",
status=200,
)
yield rsps


def test_list_project_access_tokens(gl, resp_list_project_access_token):
access_tokens = gl.projects.get(1, lazy=True).access_tokens.list()
assert len(access_tokens) == 1
assert access_tokens[0].revoked is False
assert access_tokens[0].name == "token"


def test_create_project_access_token(gl, resp_create_project_access_token):
access_tokens = gl.projects.get(1, lazy=True).access_tokens.create(
{"name": "test", "scopes": ["api"]}
)
assert access_tokens.revoked is False
assert access_tokens.user_id == 141
assert access_tokens.expires_at == "2021-01-31"


def test_revoke_project_access_token(
gl, resp_list_project_access_token, resp_revoke_project_access_token
):
gl.projects.get(1, lazy=True).access_tokens.delete(42)
access_token = gl.projects.get(1, lazy=True).access_tokens.list()[0]
access_token.delete()
18 changes: 18 additions & 0 deletions gitlab/v4/objects/project_access_tokens.py
@@ -0,0 +1,18 @@
from gitlab.base import * # noqa
from gitlab.mixins import * # noqa


__all__ = [
"ProjectAccessToken",
"ProjectAccessTokenManager",
]


class ProjectAccessToken(ObjectDeleteMixin, RESTObject):
pass


class ProjectAccessTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/projects/%(project_id)s/access_tokens"
_obj_cls = ProjectAccessToken
_from_parent_attrs = {"project_id": "id"}
2 changes: 2 additions & 0 deletions gitlab/v4/objects/projects.py
Expand Up @@ -3,6 +3,7 @@
from gitlab.base import * # noqa
from gitlab.mixins import * # noqa

from .project_access_tokens import ProjectAccessTokenManager
from .access_requests import ProjectAccessRequestManager
from .badges import ProjectBadgeManager
from .boards import ProjectBoardManager
Expand Down Expand Up @@ -94,6 +95,7 @@ class GroupProjectManager(ListMixin, RESTManager):
class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "path"
_managers = (
("access_tokens", "ProjectAccessTokenManager"),
("accessrequests", "ProjectAccessRequestManager"),
("approvals", "ProjectApprovalManager"),
("approvalrules", "ProjectApprovalRuleManager"),
Expand Down

0 comments on commit 1becef0

Please sign in to comment.