kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
123 wiersze
4.1 KiB
Python
123 wiersze
4.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
from __future__ import unicode_literals, absolute_import
|
|
|
|
import binascii
|
|
import os
|
|
import uuid
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth.models import AbstractUser, Permission
|
|
from django.urls import reverse
|
|
from django.db import models
|
|
from django.utils.encoding import python_2_unicode_compatible
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from funkwhale_api.common import fields
|
|
from funkwhale_api.common import preferences
|
|
|
|
|
|
def get_token():
|
|
return binascii.b2a_hex(os.urandom(15)).decode('utf-8')
|
|
|
|
|
|
PERMISSIONS_CONFIGURATION = {
|
|
'federation': {
|
|
'label': 'Manage library federation',
|
|
'help_text': 'Follow other instances, accept/deny library follow requests...',
|
|
},
|
|
'library': {
|
|
'label': 'Manage library',
|
|
'help_text': 'Manage library, delete files, tracks, artists, albums...',
|
|
},
|
|
'settings': {
|
|
'label': 'Manage instance-level settings',
|
|
'help_text': '',
|
|
},
|
|
'upload': {
|
|
'label': 'Upload new content to the library',
|
|
'help_text': '',
|
|
},
|
|
}
|
|
|
|
PERMISSIONS = sorted(PERMISSIONS_CONFIGURATION.keys())
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class User(AbstractUser):
|
|
|
|
# First Name and Last Name do not cover name patterns
|
|
# around the globe.
|
|
name = models.CharField(_("Name of User"), blank=True, max_length=255)
|
|
|
|
# updated on logout or password change, to invalidate JWT
|
|
secret_key = models.UUIDField(default=uuid.uuid4, null=True)
|
|
privacy_level = fields.get_privacy_field()
|
|
|
|
# Unfortunately, Subsonic API assumes a MD5/password authentication
|
|
# scheme, which is weak in terms of security, and not achievable
|
|
# anyway since django use stronger schemes for storing passwords.
|
|
# Users that want to use the subsonic API from external client
|
|
# should set this token and use it as their password in such clients
|
|
subsonic_api_token = models.CharField(
|
|
blank=True, null=True, max_length=255)
|
|
|
|
# permissions
|
|
permission_federation = models.BooleanField(
|
|
PERMISSIONS_CONFIGURATION['federation']['label'],
|
|
help_text=PERMISSIONS_CONFIGURATION['federation']['help_text'],
|
|
default=False)
|
|
permission_library = models.BooleanField(
|
|
PERMISSIONS_CONFIGURATION['library']['label'],
|
|
help_text=PERMISSIONS_CONFIGURATION['library']['help_text'],
|
|
default=False)
|
|
permission_settings = models.BooleanField(
|
|
PERMISSIONS_CONFIGURATION['settings']['label'],
|
|
help_text=PERMISSIONS_CONFIGURATION['settings']['help_text'],
|
|
default=False)
|
|
permission_upload = models.BooleanField(
|
|
PERMISSIONS_CONFIGURATION['upload']['label'],
|
|
help_text=PERMISSIONS_CONFIGURATION['upload']['help_text'],
|
|
default=False)
|
|
|
|
def __str__(self):
|
|
return self.username
|
|
|
|
def get_permissions(self):
|
|
defaults = preferences.get('users__default_permissions')
|
|
perms = {}
|
|
for p in PERMISSIONS:
|
|
v = (
|
|
self.is_superuser or
|
|
getattr(self, 'permission_{}'.format(p)) or
|
|
p in defaults
|
|
)
|
|
perms[p] = v
|
|
return perms
|
|
|
|
def has_permissions(self, *perms, operator='and'):
|
|
if operator not in ['and', 'or']:
|
|
raise ValueError('Invalid operator {}'.format(operator))
|
|
permissions = self.get_permissions()
|
|
checker = all if operator == 'and' else any
|
|
return checker([permissions[p] for p in perms])
|
|
|
|
def get_absolute_url(self):
|
|
return reverse('users:detail', kwargs={'username': self.username})
|
|
|
|
def update_secret_key(self):
|
|
self.secret_key = uuid.uuid4()
|
|
return self.secret_key
|
|
|
|
def update_subsonic_api_token(self):
|
|
self.subsonic_api_token = get_token()
|
|
return self.subsonic_api_token
|
|
|
|
def set_password(self, raw_password):
|
|
super().set_password(raw_password)
|
|
self.update_secret_key()
|
|
if self.subsonic_api_token:
|
|
self.update_subsonic_api_token()
|
|
|
|
def get_activity_url(self):
|
|
return settings.FUNKWHALE_URL + '/@{}'.format(self.username)
|