diff options
| author | rr- | 2016-04-03 18:00:38 +0200 |
|---|---|---|
| committer | rr- | 2016-04-03 18:13:22 +0200 |
| commit | 1ed17a2046d69c03d225d4080e04ea78b888b5ee (patch) | |
| tree | 497833630793817b1f78185b8c6dd3957d33e869 /server/szurubooru/api/user_api.py | |
| parent | 8bdcb04665f5f9aea4191ce1af373023764a32ed (diff) | |
server/users: add editing users
Diffstat (limited to 'server/szurubooru/api/user_api.py')
| -rw-r--r-- | server/szurubooru/api/user_api.py | 76 |
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)} |