server/users: add user removal

This commit is contained in:
rr- 2016-04-09 09:21:56 +02:00
parent 6ff160b9c6
commit 450a61c1e1
3 changed files with 98 additions and 5 deletions

19
API.md
View file

@ -17,6 +17,7 @@
- [Creating user](#creating-user)
- [Updating user](#updating-user)
- [Getting user](#getting-user)
- [Removing user](#removing-user)
- [Password reset - step 1: mail request](#password-reset---step-2-confirmation)
- [Password reset - step 2: confirmation](#password-reset---step-2-confirmation)
@ -95,6 +96,7 @@ Output:
```
...where `<user>` is an [user resource](#user) and `query` contains standard
[search query](#search).
Errors: if privileges are too low.
Searches for users.
@ -143,7 +145,7 @@ Output:
```
...where `<user>` is an [user resource](#user).
Errors: if such user already exists (names are case insensitive), or either of
user name, password and email are invalid.
user name, password and email are invalid, or privileges are too low.
Creates a new user using specified parameters. Names and passwords must match
`user_name_regex` and `password_regex` from server's configuration,
@ -174,7 +176,7 @@ Output:
Errors: if the user does not exist, or the user with new name already exists
(names are case insensitive), or either of user name, password, email or rank
are invalid, or the user is trying to update their or someone else's rank to
higher than their own.
higher than their own, or privileges are too low.
Updates an existing user using specified parameters. Names and passwords must
match `user_name_regex` and `password_regex` from server's configuration,
@ -191,11 +193,22 @@ Output:
}
```
...where `<user>` is an [user resource](#user).
Errors: if the user does not exist.
Errors: if the user does not exist or privileges are too low.
Retrieves information about an existing user.
### Removing user
Request: `DELETE /user/<name>`
Output:
```json5
{}
```
Errors: if the user does not exist or privileges are too low.
Deletes existing user.
### Password reset - step 1: mail request
Request: `GET /password-reset/<email-or-name>`
Output:

View file

@ -111,3 +111,19 @@ class UserDetailApi(BaseApi):
context.session.commit()
return {'user': _serialize_user(context.user, user)}
def delete(self, context, user_name):
''' Delete an existing user. '''
user = users.get_by_name(context.session, user_name)
if not user:
raise errors.NotFoundError('User %r not found.' % user_name)
if context.user.user_id == user.user_id:
infix = 'self'
else:
infix = 'any'
auth.verify_privilege(context.user, 'users:delete:%s' % infix)
context.session.delete(user)
context.session.commit()
return {}

View file

@ -10,8 +10,6 @@ class TestRetrievingUsers(DatabaseTestCase):
util.mock_config({
'privileges': {
'users:list': 'regular_user',
'users:view': 'regular_user',
'users:create': 'regular_user',
},
'avatar_thumbnail_size': 200,
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
@ -39,6 +37,30 @@ class TestRetrievingUsers(DatabaseTestCase):
api_ = api.UserListApi()
self.assertRaises(errors.AuthError, api_.get, self.context)
def test_retrieving_non_existing(self):
self.context.user.rank = 'regular_user'
util.mock_params(self.context, {'query': 'asd', 'page': 1})
api_ = api.UserListApi()
result = api_.get(self.context)
self.assertEqual(result['query'], 'asd')
self.assertEqual(result['page'], 1)
self.assertEqual(result['pageSize'], 100)
self.assertEqual(result['total'], 0)
self.assertEqual([u['name'] for u in result['users']], [])
class TestRetrievingUser(DatabaseTestCase):
def setUp(self):
super().setUp()
util.mock_config({
'privileges': {
'users:view': 'regular_user',
},
'avatar_thumbnail_size': 200,
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {},
})
util.mock_context(self)
def test_retrieving_single(self):
user = util.mock_user('u1', 'regular_user')
self.session.add(user)
@ -65,6 +87,48 @@ class TestRetrievingUsers(DatabaseTestCase):
api_ = api.UserDetailApi()
self.assertRaises(errors.AuthError, api_.get, self.context, '-')
class TestDeletingUser(DatabaseTestCase):
def setUp(self):
super().setUp()
util.mock_config({
'privileges': {
'users:delete:self': 'regular_user',
'users:delete:any': 'mod',
},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {},
})
util.mock_context(self)
def test_removing_oneself(self):
user1 = util.mock_user('u1', 'regular_user')
user2 = util.mock_user('u2', 'regular_user')
self.session.add_all([user1, user2])
self.session.commit()
self.context.user.user_id = user1.user_id
self.context.user.rank = 'regular_user'
api_ = api.UserDetailApi()
self.assertRaises(errors.AuthError, api_.delete, self.context, 'u2')
api_.delete(self.context, 'u1')
self.assertEqual(self.session.query(db.User).filter_by(name='u1').all(), [])
def test_removing_someone_else(self):
user1 = util.mock_user('u1', 'regular_user')
user2 = util.mock_user('u2', 'regular_user')
self.session.add_all([user1, user2])
self.session.commit()
self.context.user.rank = 'mod'
api_ = api.UserDetailApi()
api_.delete(self.context, 'u1')
api_.delete(self.context, 'u2')
self.assertEqual(self.session.query(db.User).filter_by(name='u1').all(), [])
self.assertEqual(self.session.query(db.User).filter_by(name='u2').all(), [])
def test_removing_non_existing(self):
self.context.user.rank = 'regular_user'
api_ = api.UserDetailApi()
self.assertRaises(errors.NotFoundError, api_.delete, self.context, 'bad')
class TestCreatingUser(DatabaseTestCase):
def setUp(self):
super().setUp()