mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
Cleanup & fix serializer validation
This commit is contained in:
parent
e91e3932ca
commit
e425746620
@ -584,11 +584,16 @@ Additionally, a token can be set to expire at a specific time. This can be usefu
|
||||
|
||||
#### Client IP Restriction
|
||||
|
||||
!!! note
|
||||
This feature was introduced in NetBox v3.3.
|
||||
|
||||
Each API token can optionally be restricted by client IP address. If one or more allowed IP prefixes/addresses is defined for a token, authentication will fail for any client connecting from an IP address outside the defined range(s). This enables restricting the use a token to a specific client. (By default, any client IP address is permitted.)
|
||||
|
||||
#### Creating Tokens for Other Users
|
||||
|
||||
It is possible to provision authentication tokens for other users via the REST API. To do, so the requesting user must have the `users.grant_token` permission assigned. While all users have inherent permission to create their own tokens, this permission is required to enable the creation of tokens for other users.
|
||||
|
||||

|
||||
|
||||
!!! warning "Exercise Caution"
|
||||
The ability to create tokens on behalf of other users enables the requestor to access the created token. This ability is intended e.g. for the provisioning of tokens by automated services, and should be used with extreme caution to avoid a security compromise.
|
||||
|
||||
### Authenticating to the API
|
||||
|
||||
@ -657,8 +662,3 @@ Note that we are _not_ passing an existing REST API token with this request. If
|
||||
"description": ""
|
||||
}
|
||||
```
|
||||
### Granting Other Users Tokens
|
||||
|
||||
The REST API allows granting of tokens to other users, this is restricted by the `users.grant_token` permission. This is achieved by assigning the user (or group) a permission on the Token object and specifying the `grant` action in the admin UI as shown below.
|
||||
|
||||

|
||||
|
@ -93,20 +93,14 @@ class TokenSerializer(ValidatedModelSerializer):
|
||||
return super().to_internal_value(data)
|
||||
|
||||
def validate(self, data):
|
||||
"""
|
||||
Check that the user has permissions to grant other users a token.
|
||||
"""
|
||||
if grant_user := data.get('user', None):
|
||||
request = self.context.get("request")
|
||||
if request and hasattr(request, "user"):
|
||||
user = request.user
|
||||
else:
|
||||
raise PermissionDenied("Unauthorized user.")
|
||||
|
||||
if user != grant_user and not request.user.has_perm('users.grant_token'):
|
||||
raise PermissionDenied("This user does not have permission to create tokens for other users.")
|
||||
# If the Token is being created on behalf of another user, enforce the grant_token permission.
|
||||
request = self.context.get('request')
|
||||
token_user = data.get('user')
|
||||
if token_user and token_user != request.user and not request.user.has_perm('users.grant_token'):
|
||||
raise PermissionDenied("This user does not have permission to create tokens for other users.")
|
||||
|
||||
return data
|
||||
return super().validate(data)
|
||||
|
||||
|
||||
class TokenProvisionSerializer(serializers.Serializer):
|
||||
|
@ -155,33 +155,21 @@ class TokenTest(
|
||||
|
||||
def test_provision_token_other_user(self):
|
||||
"""
|
||||
Test the behavior of the token provisioning view when invalid credentials are supplied.
|
||||
Test provisioning a Token for a different User with & without the grant_token permission.
|
||||
"""
|
||||
self.add_permissions('users.add_token')
|
||||
user2 = User.objects.create_user(username='testuser2')
|
||||
data = {
|
||||
'user': user2.id,
|
||||
}
|
||||
url = reverse('users-api:token-list')
|
||||
|
||||
# Attempt to create a new Token for User2 *without* the grant_token permission
|
||||
response = self.client.post(url, data, format='json', **self.header)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_provision_token_permission(self):
|
||||
object_type = ContentType.objects.get(app_label='users', model='token')
|
||||
|
||||
objectpermission = ObjectPermission(
|
||||
name=f'Permission Token',
|
||||
actions=['view', 'add', 'change', 'delete', 'grant'],
|
||||
)
|
||||
objectpermission.save()
|
||||
objectpermission.object_types.add(object_type)
|
||||
objectpermission.users.add(self.user)
|
||||
user2 = User.objects.create_user(username='testuser2')
|
||||
data = {
|
||||
'user': user2.id,
|
||||
}
|
||||
url = reverse('users-api:token-list')
|
||||
|
||||
# Assign grant_token permission and successfully create a new Token for User2
|
||||
self.add_permissions('users.grant_token')
|
||||
response = self.client.post(url, data, format='json', **self.header)
|
||||
self.assertEqual(response.status_code, 201)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user