remove old api secret

This commit is contained in:
Laura Klünder 2023-12-01 17:40:12 +01:00
parent 5c203a7a2b
commit cf765acc00
6 changed files with 46 additions and 22 deletions

View file

@ -15,6 +15,7 @@ from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.api.models import Secret
from c3nav.control.models import UserPermissions, UserSpaceAccess
from c3nav.mapdata.forms import I18nModelFormMixin
from c3nav.mapdata.models import MapUpdate, Space
@ -159,8 +160,10 @@ class AccessPermissionForm(Form):
def get_signed_data(self, key=None):
# todo: yep, we stil need to fix this
if not self.author.permissions.api_secret:
raise ValueError('Author has no api secret.')
try:
api_secret = self.author.api_secrets.filter(scope_grant_permission=True).valid_only().get().api_secret
except Secret.DoesNotExist:
raise ValueError('Author has no feasable api secret.')
data = {
'id': self.data['access_restrictions'],
'time': int(time.time()),
@ -170,8 +173,7 @@ class AccessPermissionForm(Form):
if key is not None:
data['key'] = key
data = json.dumps(data, separators=(',', ':'))
signature = hmac.new(self.author.permissions.api_secret.encode(),
msg=data.encode(), digestmod=hashlib.sha256).digest()
signature = hmac.new(api_secret, msg=data.encode(), digestmod=hashlib.sha256).digest()
return '%s:%s' % (data, binascii.b2a_base64(signature).strip().decode())
@classmethod
@ -230,16 +232,19 @@ class AccessPermissionForm(Form):
except User.DoesNotExist:
raise SignedPermissionDataError('Author does not exist.')
try:
api_secret = author.permissions.api_secret
except AttributeError:
api_secrets = author.api_secrets.filter(
scope_grant_permission=True
).valid_only().values_list('api_secret', flat=True)
if not api_secrets:
raise SignedPermissionDataError('Author has no API secret.')
verify_signature = binascii.b2a_base64(hmac.new(api_secret.encode(),
msg=raw_data.encode(), digestmod=hashlib.sha256).digest())
print(verify_signature, signature)
if signature != verify_signature.strip().decode():
raise SignedPermissionDataError('Invalid signature.')
for api_secret in api_secrets:
verify_signature = binascii.b2a_base64(hmac.new(api_secret.encode(),
msg=raw_data.encode(), digestmod=hashlib.sha256).digest())
if signature == verify_signature.strip().decode():
break
else:
raise SignedPermissionDataError('Invalid signature.') # todo: test this!!
form = cls(author=author, expire_date=valid_until, data={
'access_restrictions': str(restrictions),

View file

@ -0,0 +1,17 @@
# Generated by Django 4.2.3 on 2023-12-01 16:38
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("control", "0010_userpermissions_mesh_control"),
("api", "0003_rename_token_logintoken_secret"),
]
operations = [
migrations.RemoveField(
model_name="userpermissions",
name="api_secret",
),
]

View file

@ -37,8 +37,6 @@ class UserPermissions(models.Model):
mesh_control = models.BooleanField(default=False, verbose_name=_('can access mesh control'))
api_secret = models.CharField(null=True, blank=True, max_length=64, verbose_name=_('API secret'))
class Meta:
verbose_name = _('User Permissions')
verbose_name_plural = _('User Permissions')

View file

@ -22,7 +22,7 @@ def grant_access(request): # todo: make class based view
token = form.get_token()
token.save()
# todo: this still needs fixing
if settings.DEBUG and request.user_permissions.api_secret:
if settings.DEBUG:
signed_data = form.get_signed_data()
print('/?'+urlencode({'access': signed_data}))
return redirect(reverse('control.access.qr', kwargs={'token': token.token}))