Skip to content

Commit 1f687b7

Browse files
authored
feat: add support for name on api token endpoints (#64493)
Adds backend support for naming API tokens. - see issue #9600 and getsentry/customer-feedback#22 - #58918 - [RFC #32](getsentry/rfcs#32)
1 parent 9785349 commit 1f687b7

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/sentry/api/endpoints/api_tokens.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.utils.decorators import method_decorator
44
from django.views.decorators.cache import never_cache
55
from rest_framework import serializers
6+
from rest_framework.fields import CharField
67
from rest_framework.permissions import IsAuthenticated
78
from rest_framework.request import Request
89
from rest_framework.response import Response
@@ -21,6 +22,7 @@
2122

2223

2324
class ApiTokenSerializer(serializers.Serializer):
25+
name = CharField(max_length=255, allow_blank=True, required=False)
2426
scopes = MultipleChoiceField(required=True, choices=settings.SENTRY_SCOPES)
2527

2628

@@ -75,6 +77,7 @@ def post(self, request: Request) -> Response:
7577

7678
token = ApiToken.objects.create(
7779
user_id=request.user.id,
80+
name=result.get("name", None),
7881
scope_list=result["scopes"],
7982
refresh_token=None,
8083
expires_at=None,

src/sentry/api/serializers/models/apitoken.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def serialize(self, obj, attrs, user, **kwargs):
2121
data = {
2222
"id": str(obj.id),
2323
"scopes": obj.get_scopes(),
24+
"name": obj.name,
2425
"application": attrs["application"],
2526
"expiresAt": obj.expires_at,
2627
"dateCreated": obj.date_added,

tests/sentry/api/endpoints/test_api_tokens.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,42 @@ def test_invalid_choice(self):
8484
assert response.status_code == 400
8585
assert not ApiToken.objects.filter(user=self.user).exists()
8686

87+
def test_with_name(self):
88+
self.login_as(self.user)
89+
url = reverse("sentry-api-0-api-tokens")
90+
response = self.client.post(
91+
url,
92+
data={"name": "testname1", "scopes": ["event:read"]},
93+
)
94+
assert response.status_code == 201
95+
96+
token = ApiToken.objects.get(user=self.user)
97+
assert token.name == "testname1"
98+
99+
response = self.client.get(url)
100+
assert response.status_code == 200, response.content
101+
assert len(response.data) == 1
102+
103+
assert response.data[0]["name"] == "testname1"
104+
105+
def test_without_name(self):
106+
self.login_as(self.user)
107+
url = reverse("sentry-api-0-api-tokens")
108+
response = self.client.post(
109+
url,
110+
data={"scopes": ["event:read"]},
111+
)
112+
assert response.status_code == 201
113+
114+
token = ApiToken.objects.get(user=self.user)
115+
assert token.name is None
116+
117+
response = self.client.get(url)
118+
assert response.status_code == 200, response.content
119+
assert len(response.data) == 1
120+
121+
assert response.data[0]["name"] is None
122+
87123

88124
@control_silo_test
89125
class ApiTokensDeleteTest(APITestCase):

0 commit comments

Comments
 (0)