server/users: add user removal
This commit is contained in:
parent
6ff160b9c6
commit
450a61c1e1
3 changed files with 98 additions and 5 deletions
19
API.md
19
API.md
|
@ -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:
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue