server/users: make user names case insensitive

This commit is contained in:
rr- 2016-04-06 17:12:40 +02:00
parent 42fdb49d1a
commit 1fb2f53914
3 changed files with 31 additions and 11 deletions

View file

@ -48,12 +48,11 @@ class UserListApi(BaseApi):
except KeyError as ex: except KeyError as ex:
raise errors.ValidationError('Field %r not found.' % ex.args[0]) raise errors.ValidationError('Field %r not found.' % ex.args[0])
user = users.create_user(name, password, email) if users.get_by_name(context.session, name):
try:
context.session.add(user)
context.session.commit()
except sqlalchemy.exc.IntegrityError:
raise errors.IntegrityError('User %r already exists.' % name) raise errors.IntegrityError('User %r already exists.' % name)
user = users.create_user(name, password, email)
context.session.add(user)
context.session.commit()
return {'user': _serialize_user(context.user, user)} return {'user': _serialize_user(context.user, user)}
class UserDetailApi(BaseApi): class UserDetailApi(BaseApi):
@ -80,6 +79,9 @@ class UserDetailApi(BaseApi):
if 'name' in context.request: if 'name' in context.request:
auth.verify_privilege(context.user, 'users:edit:%s:name' % infix) auth.verify_privilege(context.user, 'users:edit:%s:name' % infix)
other_user = users.get_by_name(context.session, context.request['name'])
if other_user and other_user.user_id != user.user_id:
raise errors.IntegrityError('User %r already exists.' % user.name)
users.update_name(user, context.request['name']) users.update_name(user, context.request['name'])
if 'password' in context.request: if 'password' in context.request:
@ -96,9 +98,5 @@ class UserDetailApi(BaseApi):
# TODO: avatar # TODO: avatar
try: context.session.commit()
context.session.commit()
except sqlalchemy.exc.IntegrityError:
raise errors.IntegrityError('User %r already exists.' % user.name)
return {'user': _serialize_user(context.user, user)} return {'user': _serialize_user(context.user, user)}

View file

@ -145,6 +145,16 @@ class TestCreatingUser(DatabaseTestCase):
self.api.post(self.context) self.api.post(self.context)
self.assertRaises(errors.IntegrityError, self.api.post, self.context) self.assertRaises(errors.IntegrityError, self.api.post, self.context)
def test_creating_user_that_already_exists_insensitive(self):
self.context.request = {
'name': 'chewie',
'email': 'asd@asd.asd',
'password': 'oks',
}
self.api.post(self.context)
self.context.name = 'chewie'
self.assertRaises(errors.IntegrityError, self.api.post, self.context)
def test_missing_field(self): def test_missing_field(self):
for key in ['name', 'email', 'password']: for key in ['name', 'email', 'password']:
self.context.request = { self.context.request = {
@ -272,6 +282,15 @@ class TestUpdatingUser(DatabaseTestCase):
self.assertRaises( self.assertRaises(
errors.IntegrityError, self.api.put, self.context, 'me') errors.IntegrityError, self.api.put, self.context, 'me')
def test_user_trying_to_become_someone_else_insensitive(self):
user1 = _create_user('me', 'regular_user')
user2 = _create_user('her', 'regular_user')
self.session.add_all([user1, user2])
self.context.user = user1
self.context.request = {'name': 'HER'}
self.assertRaises(
errors.IntegrityError, self.api.put, self.context, 'me')
def test_mods_trying_to_become_admin(self): def test_mods_trying_to_become_admin(self):
user1 = _create_user('u1', 'mod') user1 = _create_user('u1', 'mod')
user2 = _create_user('u2', 'mod') user2 = _create_user('u2', 'mod')

View file

@ -1,5 +1,6 @@
import re import re
from datetime import datetime from datetime import datetime
from sqlalchemy import func
from szurubooru import config, db, errors from szurubooru import config, db, errors
from szurubooru.util import auth, misc from szurubooru.util import auth, misc
@ -64,4 +65,6 @@ def reset_password(user):
def get_by_name(session, name): def get_by_name(session, name):
''' Retrieve an user by its name. ''' ''' Retrieve an user by its name. '''
return session.query(db.User).filter_by(name=name).first() return session.query(db.User) \
.filter(func.lower(db.User.name) == func.lower(name)) \
.first()