server/users: fix hiding email from admins etc

This commit is contained in:
rr- 2016-04-29 13:08:41 +02:00
parent d67a1b2f1c
commit da5b32feeb
12 changed files with 36 additions and 22 deletions

3
API.md
View file

@ -1181,7 +1181,8 @@ A single user.
**Field meaning**
- `<name>`: the user name.
- `<email>`: the user email. It is available only if the request is
authenticated by the same user.
authenticated by the same user, or the authenticated user can change the
email.
- `<rank>`: the user rank, which effectively affects their privileges. The
available ranks are stored in the server configuration.
- `<rank-name>`: the text representation of user's rank. Like `<rank>`, the

View file

@ -27,7 +27,8 @@ class UserListApi(BaseApi):
ctx.get_file('avatar'))
ctx.session.add(user)
ctx.session.commit()
return users.serialize_user_with_details(user, ctx.user)
return users.serialize_user_with_details(
user, ctx.user, force_show_email=True)
class UserDetailApi(BaseApi):
def get(self, ctx, user_name):

View file

@ -36,15 +36,16 @@ def is_valid_password(user, password):
]
return valid_hash in possible_hashes
def verify_privilege(user, privilege_name):
''' Throw an AuthError if the given user doesn't have given privilege. '''
def has_privilege(user, privilege_name):
all_ranks = config.config['ranks']
assert privilege_name in config.config['privileges']
assert user.rank in all_ranks
minimal_rank = config.config['privileges'][privilege_name]
good_ranks = all_ranks[all_ranks.index(minimal_rank):]
if user.rank not in good_ranks:
return user.rank in good_ranks
def verify_privilege(user, privilege_name):
if not has_privilege(user, privilege_name):
raise errors.AuthError('Insufficient privileges to do this.')
def generate_authentication_token(user):

View file

@ -13,7 +13,7 @@ class InvalidPasswordError(errors.ValidationError): pass
class InvalidRankError(errors.ValidationError): pass
class InvalidAvatarError(errors.ValidationError): pass
def serialize_user(user, authenticated_user):
def serialize_user(user, authenticated_user, force_show_email=False):
if not user:
return {}
@ -23,7 +23,8 @@ def serialize_user(user, authenticated_user):
'rankName': config.config['rank_names'].get(user.rank, 'Unknown'),
'creationTime': user.creation_time,
'lastLoginTime': user.last_login_time,
'avatarStyle': user.avatar_style
'avatarStyle': user.avatar_style,
'email': user.email,
}
if user.avatar_style == user.AVATAR_GRAVATAR:
@ -36,13 +37,15 @@ def serialize_user(user, authenticated_user):
ret['avatarUrl'] = '%s/avatars/%s.jpg' % (
config.config['data_url'].rstrip('/'), user.name.lower())
if authenticated_user.user_id == user.user_id:
ret['email'] = user.email
if authenticated_user.user_id != user.user_id \
and not force_show_email \
and not auth.has_privilege(authenticated_user, 'users:edit:any:email'):
del ret['email']
return ret
def serialize_user_with_details(user, authenticated_user):
return {'user': serialize_user(user, authenticated_user)}
def serialize_user_with_details(user, authenticated_user, **kwargs):
return {'user': serialize_user(user, authenticated_user, **kwargs)}
def get_user_count():
return db.session.query(db.User).count()

View file

@ -136,7 +136,6 @@ class SearchExecutor(object):
sort_desc: lambda input: input.desc(),
None: lambda input: input,
}
print(sort)
transform = transform_map[sort]
return query.order_by(transform(column))

View file

@ -6,9 +6,12 @@ from szurubooru.func import util, comments, scores
@pytest.fixture
def test_ctx(config_injector, context_factory, user_factory, comment_factory):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {'comments:score': 'regular_user'},
'privileges': {
'comments:score': 'regular_user',
'users:edit:any:email': 'mod',
},
'thumbnails': {'avatar_width': 200},
})
db.session.flush()

View file

@ -6,13 +6,14 @@ from szurubooru.func import util, comments
@pytest.fixture
def test_ctx(context_factory, config_injector, user_factory, comment_factory):
config_injector({
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
'privileges': {
'comments:list': 'regular_user',
'comments:view': 'regular_user',
'users:edit:any:email': 'mod',
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory

View file

@ -11,6 +11,7 @@ def test_ctx(config_injector, context_factory, user_factory, comment_factory):
'privileges': {
'comments:edit:self': 'regular_user',
'comments:edit:any': 'mod',
'users:edit:any:email': 'mod',
},
'thumbnails': {'avatar_width': 200},
})

View file

@ -6,9 +6,12 @@ from szurubooru.func import util, posts
@pytest.fixture
def test_ctx(config_injector, context_factory, user_factory, post_factory):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {'posts:favorite': 'regular_user'},
'privileges': {
'posts:favorite': 'regular_user',
'users:edit:any:email': 'mod',
},
'thumbnails': {'avatar_width': 200},
})
db.session.flush()

View file

@ -46,6 +46,7 @@ def test_creating_user(test_ctx, fake_datetime):
'name': 'chewie1',
'rank': 'admin',
'rankName': 'Unknown',
'email': 'asd@asd.asd',
}
}
user = users.get_user_by_name('chewie1')

View file

@ -6,13 +6,14 @@ from szurubooru.func import util, users
@pytest.fixture
def test_ctx(context_factory, config_injector, user_factory):
config_injector({
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
'privileges': {
'users:list': 'regular_user',
'users:view': 'regular_user',
'users:edit:any:email': 'mod',
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory

View file

@ -12,7 +12,6 @@ def verify_unpaged(executor):
def verify(input, expected_comment_text):
actual_count, actual_comments = executor.execute(
input, page=1, page_size=100)
print(actual_comments)
actual_comment_text = [c.text for c in actual_comments]
assert actual_count == len(expected_comment_text)
assert actual_comment_text == expected_comment_text