aboutsummaryrefslogtreecommitdiff
path: root/server/szurubooru/api/user_api.py
diff options
context:
space:
mode:
authorrr-2016-04-03 18:00:38 +0200
committerrr-2016-04-03 18:13:22 +0200
commit1ed17a2046d69c03d225d4080e04ea78b888b5ee (patch)
tree497833630793817b1f78185b8c6dd3957d33e869 /server/szurubooru/api/user_api.py
parent8bdcb04665f5f9aea4191ce1af373023764a32ed (diff)
server/users: add editing users
Diffstat (limited to 'server/szurubooru/api/user_api.py')
-rw-r--r--server/szurubooru/api/user_api.py76
1 files changed, 71 insertions, 5 deletions
diff --git a/server/szurubooru/api/user_api.py b/server/szurubooru/api/user_api.py
index 8bb6ac8..e4134c6 100644
--- a/server/szurubooru/api/user_api.py
+++ b/server/szurubooru/api/user_api.py
@@ -1,9 +1,11 @@
''' Exports UserListApi and UserDetailApi. '''
+import re
import sqlalchemy
from szurubooru.api.base_api import BaseApi
-from szurubooru.errors import IntegrityError, ValidationError, NotFoundError
+from szurubooru.errors import IntegrityError, ValidationError, NotFoundError, AuthError
from szurubooru.services.search import UserSearchConfig, SearchExecutor
+from szurubooru.util import is_valid_email
def _serialize_user(authenticated_user, user):
ret = {
@@ -45,7 +47,7 @@ class UserListApi(BaseApi):
self._auth_service.verify_privilege(context.user, 'users:create')
try:
- name = context.request['name']
+ name = context.request['name'].strip()
password = context.request['password']
email = context.request['email'].strip()
except KeyError as ex:
@@ -61,8 +63,12 @@ class UserListApi(BaseApi):
class UserDetailApi(BaseApi):
''' API for individual users. '''
- def __init__(self, auth_service, user_service):
+ def __init__(self, config, auth_service, password_service, user_service):
super().__init__()
+ self._available_access_ranks = config['service']['user_ranks']
+ self._name_regex = config['service']['user_name_regex']
+ self._password_regex = config['service']['password_regex']
+ self._password_service = password_service
self._auth_service = auth_service
self._user_service = user_service
@@ -76,5 +82,65 @@ class UserDetailApi(BaseApi):
def put(self, request, context, user_name):
''' Updates an existing user. '''
- self._auth_service.verify_privilege(context.user, 'users:edit')
- return {'message': 'Updating user ' + user_name}
+ user = self._user_service.get_by_name(context.session, user_name)
+ if not user:
+ raise NotFoundError('User %r not found.' % user_name)
+
+ if context.user.user_id == user.user_id:
+ infix = 'self'
+ else:
+ infix = 'any'
+
+ if 'name' in context.request:
+ self._auth_service.verify_privilege(
+ context.user, 'users:edit:%s:name' % infix)
+ name = context.request['name'].strip()
+ if not re.match(self._name_regex, name):
+ raise ValidationError(
+ 'Name must satisfy regex %r.' % self._name_regex)
+ user.name = name
+
+ if 'password' in context.request:
+ password = context.request['password']
+ self._auth_service.verify_privilege(
+ context.user, 'users:edit:%s:pass' % infix)
+ if not re.match(self._password_regex, password):
+ raise ValidationError(
+ 'Password must satisfy regex %r.' % self._password_regex)
+ user.password_salt = self._password_service.create_password()
+ user.password_hash = self._password_service.get_password_hash(
+ user.password_salt, password)
+
+ if 'email' in context.request:
+ self._auth_service.verify_privilege(
+ context.user, 'users:edit:%s:email' % infix)
+ email = context.request['email'].strip()
+ if not is_valid_email(email):
+ raise ValidationError('%r is not a vaild email address.' % email)
+ # prefer nulls to empty strings in the DB
+ if not email:
+ email = None
+ user.email = email
+
+ if 'accessRank' in context.request:
+ self._auth_service.verify_privilege(
+ context.user, 'users:edit:%s:rank' % infix)
+ rank = context.request['accessRank'].strip()
+ if not rank in self._available_access_ranks:
+ raise ValidationError(
+ 'Bad access rank. Valid access ranks: %r' \
+ % self._available_access_ranks)
+ if self._available_access_ranks.index(context.user.access_rank) \
+ < self._available_access_ranks.index(rank):
+ raise AuthError(
+ 'Trying to set higher access rank than one has')
+ user.access_rank = rank
+
+ # TODO: avatar
+
+ try:
+ context.session.commit()
+ except sqlalchemy.exc.IntegrityError:
+ raise IntegrityError('User %r already exists.' % name)
+
+ return {'user': _serialize_user(context.user, user)}

© 2015 - 2026 Jakob L. Kreuze