server/users: hardcode available ranks

This commit is contained in:
rr- 2016-05-08 16:59:25 +02:00
parent 58964bcdc9
commit 198cb0af3e
37 changed files with 359 additions and 383 deletions

20
API.md
View file

@ -1122,9 +1122,8 @@ data.
style can be either `gravatar` or `manual`. `manual` avatar style requires
client to pass also `avatar` file - see [file uploads](#file-uploads) for
details. If the rank is empty and the user happens to be the first user
ever created, they're granted highest available rank, becoming an
administrator, whereas subsequent users will be given the rank indicated by
`default_rank` in the server's configuration.
ever created, become an administrator, whereas subsequent users will be
given the rank indicated by `default_rank` in the server's configuration.
## Updating user
- **Request**
@ -1342,7 +1341,6 @@ A single user.
"name": <name>,
"email": <email>,
"rank": <rank>,
"rankName": <rank-name>,
"lastLoginTime": <last-login-time>,
"creationTime": <creation-time>,
"avatarStyle": <avatar-style>,
@ -1355,10 +1353,16 @@ A single user.
- `<email>`: the user email. It is available only if the request is
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
possible values depend on the server configuration.
- `<rank>`: the user rank, which effectively affects their privileges.
Possible values:
- `"restricted"`: restricted user
- `"regular"`: regular user
- `"power"`: power user
- `"moderator"`: moderator
- `"administrator"`: administrator
- `<last-login-time>`: the last login time, formatted as per RFC 3339.
- `<creation-time>`: the user registration time, formatted as per RFC 3339.
- `<avatarStyle>`: how to render the user avatar.

View file

@ -11,6 +11,15 @@ class Api {
this.userName = null;
this.userPassword = null;
this.cache = {};
this.allRanks = [
'anonymous',
'restricted',
'regular',
'power',
'moderator',
'administrator',
'nobody',
];
}
get(url) {
@ -75,7 +84,7 @@ class Api {
continue;
}
const rankName = config.privileges[privilege];
const rankIndex = config.ranks.indexOf(rankName);
const rankIndex = this.allRanks.indexOf(rankName);
if (minViableRank === null || rankIndex < minViableRank) {
minViableRank = rankIndex;
}
@ -84,7 +93,7 @@ class Api {
console.error('Bad privilege name: ' + lookup);
}
let myRank = this.user !== null ?
config.ranks.indexOf(this.user.rank) :
this.allRanks.indexOf(this.user.rank) :
0;
return myRank >= minViableRank;
}

View file

@ -14,6 +14,16 @@ const UserListHeaderView = require('../views/user_list_header_view.js');
const UserListPageView = require('../views/user_list_page_view.js');
const EmptyView = require('../views/empty_view.js');
const rankNames = {
anonymous: 'Anonymous',
restricted: 'Restricted user',
regular: 'Regular user',
power: 'Power user',
moderator: 'Moderator',
administrator: 'Administrator',
nobody: 'Nobody',
};
class UsersController {
constructor() {
this.registrationView = new RegistrationView();
@ -86,6 +96,7 @@ class UsersController {
next();
} else {
api.get('/user/' + ctx.params.name).then(response => {
response.user.rankName = rankNames[response.user.rank];
ctx.state.user = response.user;
ctx.save();
this.user = response.user;
@ -209,18 +220,17 @@ class UsersController {
const isLoggedIn = api.isLoggedIn(user);
const infix = isLoggedIn ? 'self' : 'any';
const myRankIdx = api.user ? config.ranks.indexOf(api.user.rank) : 0;
const rankNames = Object.values(config.rankNames);
const myRankIdx = api.user ? api.allRanks.indexOf(api.user.rank) : 0;
let ranks = {};
for (let rankIdx of misc.range(config.ranks.length)) {
const rankIdentifier = config.ranks[rankIdx];
for (let rankIdx of misc.range(api.allRanks.length)) {
const rankIdentifier = api.allRanks[rankIdx];
if (rankIdentifier === 'anonymous') {
continue;
}
if (rankIdx > myRankIdx) {
continue;
}
ranks[rankIdentifier] = rankNames[rankIdx];
ranks[rankIdentifier] = Object.values(rankNames)[rankIdx];
}
if (isLoggedIn) {

View file

@ -39,22 +39,7 @@ limits:
tag_name_regex: ^:?[a-zA-Z0-9_-]+$
tag_category_name_regex: ^.{1,}$
# changing ranks after deployment may require manual tweaks to the database.
ranks:
- anonymous
- regular_user
- power_user
- mod
- admin
- nobody
rank_names:
anonymous: 'Anonymous user'
regular_user: 'Regular user'
power_user: 'Power user'
mod: 'Moderator'
admin: 'Administrator'
nobody: 'God'
default_rank: regular_user
default_rank: regular
# don't change these, unless you want to annoy people. if you do customize
# them though, make sure to update the instructions in the registration form
@ -64,63 +49,63 @@ user_name_regex: '^[a-zA-Z0-9_-]{1,32}$'
privileges:
'users:create': anonymous
'users:list': regular_user
'users:view': regular_user
'users:edit:any:name': mod
'users:edit:any:pass': mod
'users:edit:any:email': mod
'users:edit:any:avatar': mod
'users:edit:any:rank': mod
'users:edit:self:name': regular_user
'users:edit:self:pass': regular_user
'users:edit:self:email': regular_user
'users:edit:self:avatar': regular_user
'users:edit:self:rank': mod # one can't promote themselves or anyone to upper rank than their own.
'users:delete:any': admin
'users:delete:self': regular_user
'users:list': regular
'users:view': regular
'users:edit:any:name': moderator
'users:edit:any:pass': moderator
'users:edit:any:email': moderator
'users:edit:any:avatar': moderator
'users:edit:any:rank': moderator
'users:edit:self:name': regular
'users:edit:self:pass': regular
'users:edit:self:email': regular
'users:edit:self:avatar': regular
'users:edit:self:rank': moderator # one can't promote themselves or anyone to upper rank than their own.
'users:delete:any': administrator
'users:delete:self': regular
'posts:create:anonymous': regular_user
'posts:create:identified': regular_user
'posts:create:anonymous': regular
'posts:create:identified': regular
'posts:list': anonymous
'posts:view': anonymous
'posts:edit:content': power_user
'posts:edit:flags': regular_user
'posts:edit:notes': regular_user
'posts:edit:relations': regular_user
'posts:edit:safety': power_user
'posts:edit:source': regular_user
'posts:edit:tags': regular_user
'posts:edit:thumbnail': power_user
'posts:feature': mod
'posts:delete': mod
'posts:score': regular_user
'posts:favorite': regular_user
'posts:edit:content': power
'posts:edit:flags': regular
'posts:edit:notes': regular
'posts:edit:relations': regular
'posts:edit:safety': power
'posts:edit:source': regular
'posts:edit:tags': regular
'posts:edit:thumbnail': power
'posts:feature': moderator
'posts:delete': moderator
'posts:score': regular
'posts:favorite': regular
'tags:create': regular_user
'tags:edit:names': power_user
'tags:edit:category': power_user
'tags:edit:implications': power_user
'tags:edit:suggestions': power_user
'tags:list': regular_user # note: will be available as data_url/tags.json anyway
'tags:create': regular
'tags:edit:names': power
'tags:edit:category': power
'tags:edit:implications': power
'tags:edit:suggestions': power
'tags:list': regular # note: will be available as data_url/tags.json anyway
'tags:view': anonymous
'tags:masstag': power_user
'tags:merge': mod
'tags:delete': mod
'tags:masstag': power
'tags:merge': moderator
'tags:delete': moderator
'tag_categories:create': mod
'tag_categories:edit:name': mod
'tag_categories:edit:color': mod
'tag_categories:create': moderator
'tag_categories:edit:name': moderator
'tag_categories:edit:color': moderator
'tag_categories:list': anonymous # note: will be available as data_url/tags.json anyway
'tag_categories:view': anonymous
'tag_categories:delete': mod
'tag_categories:delete': moderator
'comments:create': regular_user
'comments:delete:any': mod
'comments:delete:own': regular_user
'comments:edit:any': mod
'comments:edit:own': regular_user
'comments:list': regular_user
'comments:view': regular_user
'comments:score': regular_user
'comments:create': regular
'comments:delete:any': moderator
'comments:delete:own': regular
'comments:edit:any': moderator
'comments:edit:own': regular
'comments:list': regular
'comments:view': regular
'comments:score': regular
'snapshots:list': power_user
'snapshots:list': power

View file

@ -26,15 +26,12 @@ def validate_config(src):
Check whether config doesn't contain errors that might prove
lethal at runtime.
'''
all_ranks = src['ranks']
from szurubooru.db.user import User
for privilege, rank in src['privileges'].items():
if rank not in all_ranks:
if rank not in User.ALL_RANKS:
raise errors.ConfigError(
'Rank %r for privilege %r is missing' % (rank, privilege))
for rank in ['anonymous', 'admin', 'nobody']:
if rank not in all_ranks:
raise errors.ConfigError('Protected rank %r is missing' % rank)
if src['default_rank'] not in all_ranks:
if src['default_rank'] not in User.ALL_RANKS:
raise errors.ConfigError(
'Default rank %r is not on the list of known ranks' % (
src['default_rank']))

View file

@ -7,6 +7,23 @@ class User(Base):
AVATAR_GRAVATAR = 'gravatar'
AVATAR_MANUAL = 'manual'
RANK_ANONYMOUS = 'anonymous'
RANK_RESTRICTED = 'restricted'
RANK_REGULAR = 'regular'
RANK_POWER = 'power'
RANK_MODERATOR = 'moderator'
RANK_ADMINISTRATOR = 'administrator'
RANK_NOBODY = 'nobody'
ALL_RANKS = [
RANK_ANONYMOUS,
RANK_RESTRICTED,
RANK_REGULAR,
RANK_POWER,
RANK_MODERATOR,
RANK_ADMINISTRATOR,
RANK_NOBODY, # nobody can have higher privileges than administrator
]
user_id = Column('id', Integer, primary_key=True)
name = Column('name', String(50), nullable=False, unique=True)
password_hash = Column('password_hash', String(64), nullable=False)

View file

@ -1,7 +1,6 @@
import hashlib
import random
from szurubooru import config
from szurubooru import errors
from szurubooru import config, db, errors
def get_password_hash(salt, password):
''' Retrieve new-style password hash. '''
@ -37,11 +36,10 @@ def is_valid_password(user, password):
return valid_hash in possible_hashes
def has_privilege(user, privilege_name):
all_ranks = config.config['ranks']
assert privilege_name in config.config['privileges']
assert user.rank in all_ranks
assert user.rank in db.User.ALL_RANKS
minimal_rank = config.config['privileges'][privilege_name]
good_ranks = all_ranks[all_ranks.index(minimal_rank):]
good_ranks = db.User.ALL_RANKS[db.User.ALL_RANKS.index(minimal_rank):]
return user.rank in good_ranks
def verify_privilege(user, privilege_name):

View file

@ -19,7 +19,6 @@ def serialize_user(user, authenticated_user, force_show_email=False):
ret = {
'name': user.name,
'rank': user.rank,
'rankName': config.config['rank_names'].get(user.rank, 'Unknown'),
'creationTime': user.creation_time,
'lastLoginTime': user.last_login_time,
'avatarStyle': user.avatar_style,
@ -81,7 +80,7 @@ def create_user(name, password, email, auth_user):
if get_user_count() > 0:
user.rank = config.config['default_rank']
else:
user.rank = 'admin'
user.rank = db.User.RANK_ADMINISTRATOR
user.creation_time = datetime.datetime.now()
user.avatar_style = db.User.AVATAR_GRAVATAR
return user
@ -126,12 +125,11 @@ def update_user_rank(user, rank, authenticated_user):
if not rank:
raise InvalidRankError('Rank cannot be empty.')
rank = rank.strip()
available_ranks = config.config['ranks']
if not rank in available_ranks:
if not rank in db.User.ALL_RANKS:
raise InvalidRankError(
'Rank %r is invalid. Valid ranks: %r' % (rank, available_ranks))
if available_ranks.index(authenticated_user.rank) \
< available_ranks.index(rank) and get_user_count() > 0:
'Rank %r is invalid. Valid ranks: %r' % (rank, db.User.ALL_RANKS))
if db.User.ALL_RANKS.index(authenticated_user.rank) \
< db.User.ALL_RANKS.index(rank) and get_user_count() > 0:
raise errors.AuthError('Trying to set higher rank than your own.')
user.rank = rank

View file

@ -9,9 +9,7 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {'comments:create': 'regular_user'},
'privileges': {'comments:create': db.User.RANK_REGULAR},
'thumbnails': {'avatar_width': 200},
})
ret = util.dotdict()
@ -23,7 +21,7 @@ def test_ctx(
def test_creating_comment(test_ctx, fake_datetime):
post = test_ctx.post_factory()
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
db.session.add_all([post, user])
db.session.flush()
with fake_datetime('1997-01-01'):
@ -52,7 +50,7 @@ def test_creating_comment(test_ctx, fake_datetime):
])
def test_trying_to_pass_invalid_input(test_ctx, input):
post = test_ctx.post_factory()
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
db.session.add_all([post, user])
db.session.flush()
real_input = {'text': 'input', 'postId': post.post_id}
@ -73,10 +71,10 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post(
test_ctx.context_factory(
input={},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_comment_non_existing(test_ctx):
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
db.session.add_all([user])
db.session.flush()
with pytest.raises(posts.PostNotFoundError):

View file

@ -7,10 +7,9 @@ from szurubooru.func import util, comments
def test_ctx(config_injector, context_factory, user_factory, comment_factory):
config_injector({
'privileges': {
'comments:delete:self': 'regular_user',
'comments:delete:any': 'mod',
'comments:delete:self': db.User.RANK_REGULAR,
'comments:delete:any': db.User.RANK_MODERATOR,
},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -30,8 +29,8 @@ def test_deleting_own_comment(test_ctx):
assert db.session.query(db.Comment).count() == 0
def test_deleting_someones_else_comment(test_ctx):
user1 = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='mod')
user1 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank=db.User.RANK_MODERATOR)
comment = test_ctx.comment_factory(user=user1)
db.session.add(comment)
db.session.commit()
@ -40,8 +39,8 @@ def test_deleting_someones_else_comment(test_ctx):
assert db.session.query(db.Comment).count() == 0
def test_trying_to_delete_someones_else_comment_without_privileges(test_ctx):
user1 = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='regular_user')
user1 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user1)
db.session.add(comment)
db.session.commit()
@ -54,4 +53,4 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(comments.CommentNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 1)
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 1)

View file

@ -9,11 +9,9 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {
'comments:score': 'regular_user',
'users:edit:any:email': 'mod',
'comments:score': db.User.RANK_REGULAR,
'users:edit:any:email': db.User.RANK_MODERATOR,
},
'thumbnails': {'avatar_width': 200},
})
@ -26,7 +24,7 @@ def test_ctx(
return ret
def test_simple_rating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
@ -42,7 +40,7 @@ def test_simple_rating(test_ctx, fake_datetime):
assert comment.score == 1
def test_updating_rating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
@ -59,7 +57,7 @@ def test_updating_rating(test_ctx, fake_datetime):
assert comment.score == -1
def test_updating_rating_to_zero(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
@ -76,7 +74,7 @@ def test_updating_rating_to_zero(test_ctx, fake_datetime):
assert comment.score == 0
def test_deleting_rating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
@ -92,8 +90,8 @@ def test_deleting_rating(test_ctx, fake_datetime):
assert comment.score == 0
def test_ratings_from_multiple_users(test_ctx, fake_datetime):
user1 = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='regular_user')
user1 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory()
db.session.add_all([user1, user2, comment])
db.session.commit()
@ -141,7 +139,7 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put(
test_ctx.context_factory(
input={'score': 1},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
5)
def test_trying_to_rate_without_privileges(test_ctx):

View file

@ -9,12 +9,10 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'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',
'comments:list': db.User.RANK_REGULAR,
'comments:view': db.User.RANK_REGULAR,
'users:edit:any:email': db.User.RANK_MODERATOR,
},
'thumbnails': {'avatar_width': 200},
})
@ -33,7 +31,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.list_api.get(
test_ctx.context_factory(
input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == ''
assert result['page'] == 1
assert result['pageSize'] == 100
@ -53,7 +51,7 @@ def test_retrieving_single(test_ctx):
db.session.flush()
result = test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
comment.comment_id)
assert 'comment' in result
assert 'id' in result['comment']
@ -69,7 +67,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(comments.CommentNotFoundError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
5)
def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -9,12 +9,10 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord', 'mod': 'King'},
'privileges': {
'comments:edit:self': 'regular_user',
'comments:edit:any': 'mod',
'users:edit:any:email': 'mod',
'comments:edit:self': db.User.RANK_REGULAR,
'comments:edit:any': db.User.RANK_MODERATOR,
'users:edit:any:email': db.User.RANK_MODERATOR,
},
'thumbnails': {'avatar_width': 200},
})
@ -27,7 +25,7 @@ def test_ctx(
return ret
def test_simple_updating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
@ -73,12 +71,12 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put(
test_ctx.context_factory(
input={'text': 'new text'},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
5)
def test_trying_to_update_someones_comment_without_privileges(test_ctx):
user = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='regular_user')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
@ -88,8 +86,8 @@ def test_trying_to_update_someones_comment_without_privileges(test_ctx):
comment.comment_id)
def test_updating_someones_comment_with_privileges(test_ctx):
user = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='mod')
user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank=db.User.RANK_MODERATOR)
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()

View file

@ -16,7 +16,7 @@ def password_reset_api(config_injector):
def test_reset_sending_email(
password_reset_api, context_factory, user_factory):
db.session.add(user_factory(
name='u1', rank='regular_user', email='user@example.com'))
name='u1', rank=db.User.RANK_REGULAR, email='user@example.com'))
for getter in ['u1', 'user@example.com']:
mailer.send_mail = mock.MagicMock()
assert password_reset_api.get(context_factory(), getter) == {}
@ -35,14 +35,14 @@ def test_trying_to_reset_non_existing(password_reset_api, context_factory):
def test_trying_to_reset_without_email(
password_reset_api, context_factory, user_factory):
db.session.add(user_factory(name='u1', rank='regular_user', email=None))
db.session.add(user_factory(name='u1', rank=db.User.RANK_REGULAR, email=None))
with pytest.raises(errors.ValidationError):
password_reset_api.get(context_factory(), 'u1')
def test_confirming_with_good_token(
password_reset_api, context_factory, user_factory):
user = user_factory(
name='u1', rank='regular_user', email='user@example.com')
name='u1', rank=db.User.RANK_REGULAR, email='user@example.com')
old_hash = user.password_hash
db.session.add(user)
context = context_factory(
@ -58,14 +58,14 @@ def test_trying_to_confirm_non_existing(password_reset_api, context_factory):
def test_trying_to_confirm_without_token(
password_reset_api, context_factory, user_factory):
db.session.add(user_factory(
name='u1', rank='regular_user', email='user@example.com'))
name='u1', rank=db.User.RANK_REGULAR, email='user@example.com'))
with pytest.raises(errors.ValidationError):
password_reset_api.post(context_factory(input={}), 'u1')
def test_trying_to_confirm_with_bad_token(
password_reset_api, context_factory, user_factory):
db.session.add(user_factory(
name='u1', rank='regular_user', email='user@example.com'))
name='u1', rank=db.User.RANK_REGULAR, email='user@example.com'))
with pytest.raises(errors.ValidationError):
password_reset_api.post(
context_factory(input={'token': 'bad'}), 'u1')

View file

@ -8,13 +8,12 @@ from szurubooru.func import posts, tags, snapshots, net
@pytest.fixture(autouse=True)
def inject_config(config_injector):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': {'posts:create': 'regular_user'},
'privileges': {'posts:create': db.User.RANK_REGULAR},
})
def test_creating_minimal_posts(
context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user')
auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory()
db.session.add(post)
db.session.flush()
@ -60,7 +59,7 @@ def test_creating_minimal_posts(
snapshots.save_entity_creation.assert_called_once_with(post, auth_user)
def test_creating_full_posts(context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user')
auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory()
db.session.add(post)
db.session.flush()
@ -107,7 +106,7 @@ def test_creating_full_posts(context_factory, post_factory, user_factory):
def test_creating_from_url_saves_source(
config_injector, context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user')
auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory()
db.session.add(post)
db.session.flush()
@ -119,8 +118,8 @@ def test_creating_from_url_saves_source(
unittest.mock.patch('szurubooru.func.posts.create_post'), \
unittest.mock.patch('szurubooru.func.posts.update_post_source'):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': {'posts:create': 'regular_user'},
'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {'posts:create': db.User.RANK_REGULAR},
})
net.download.return_value = b'content'
posts.create_post.return_value = post
@ -139,7 +138,7 @@ def test_creating_from_url_saves_source(
def test_creating_from_url_with_source_specified(
config_injector, context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user')
auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory()
db.session.add(post)
db.session.flush()
@ -151,8 +150,8 @@ def test_creating_from_url_with_source_specified(
unittest.mock.patch('szurubooru.func.posts.create_post'), \
unittest.mock.patch('szurubooru.func.posts.update_post_source'):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': {'posts:create': 'regular_user'},
'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {'posts:create': db.User.RANK_REGULAR},
})
net.download.return_value = b'content'
posts.create_post.return_value = post
@ -182,7 +181,7 @@ def test_trying_to_omit_mandatory_field(context_factory, user_factory, field):
context_factory(
input=input,
files={'content': '...'},
user=user_factory(rank='regular_user')))
user=user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_omit_content(context_factory, user_factory):
with pytest.raises(errors.MissingRequiredFileError):
@ -192,7 +191,7 @@ def test_trying_to_omit_content(context_factory, user_factory):
'safety': 'safe',
'tags': ['tag1', 'tag2'],
},
user=user_factory(rank='regular_user')))
user=user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_create_without_privileges(context_factory, user_factory):
with pytest.raises(errors.AuthError):

View file

@ -10,9 +10,8 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'privileges': {
'posts:delete': 'regular_user',
'posts:delete': db.User.RANK_REGULAR,
},
'ranks': ['anonymous', 'regular_user'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -26,7 +25,7 @@ def test_deleting(test_ctx):
db.session.commit()
result = test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
1)
assert result == {}
assert db.session.query(db.Post).count() == 0
@ -36,7 +35,7 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(posts.PostNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')
def test_trying_to_delete_without_privileges(test_ctx):
db.session.add(test_ctx.post_factory(id=1))

View file

@ -9,11 +9,9 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {
'posts:favorite': 'regular_user',
'users:edit:any:email': 'mod',
'posts:favorite': db.User.RANK_REGULAR,
'users:edit:any:email': db.User.RANK_MODERATOR,
},
'thumbnails': {'avatar_width': 200},
})

View file

@ -10,10 +10,9 @@ def test_ctx(
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'privileges': {
'posts:feature': 'regular_user',
'posts:view': 'regular_user',
'posts:feature': db.User.RANK_REGULAR,
'posts:view': db.User.RANK_REGULAR,
},
'ranks': ['anonymous', 'regular_user'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -26,7 +25,7 @@ def test_no_featured_post(test_ctx):
assert posts.try_get_featured_post() is None
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result == {'post': None, 'snapshots': [], 'comments': []}
def test_featuring(test_ctx):
@ -36,7 +35,7 @@ def test_featuring(test_ctx):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'id': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert posts.try_get_featured_post() is not None
assert posts.try_get_featured_post().post_id == 1
assert posts.get_post_by_id(1).is_featured
@ -46,7 +45,7 @@ def test_featuring(test_ctx):
assert 'comments' in result
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert 'post' in result
assert 'id' in result['post']
assert 'snapshots' in result
@ -58,12 +57,12 @@ def test_trying_to_feature_the_same_post_twice(test_ctx):
test_ctx.api.post(
test_ctx.context_factory(
input={'id': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(posts.PostAlreadyFeaturedError):
test_ctx.api.post(
test_ctx.context_factory(
input={'id': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_featuring_one_post_after_another(test_ctx, fake_datetime):
db.session.add(test_ctx.post_factory(id=1))
@ -76,12 +75,12 @@ def test_featuring_one_post_after_another(test_ctx, fake_datetime):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'id': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with fake_datetime('1998'):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'id': 2},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert posts.try_get_featured_post() is not None
assert posts.try_get_featured_post().post_id == 2
assert not posts.get_post_by_id(1).is_featured
@ -92,7 +91,7 @@ def test_trying_to_feature_non_existing(test_ctx):
test_ctx.api.post(
test_ctx.context_factory(
input={'id': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_feature_without_privileges(test_ctx):
with pytest.raises(errors.AuthError):

View file

@ -8,9 +8,7 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {'posts:score': 'regular_user'},
'privileges': {'posts:score': db.User.RANK_REGULAR},
'thumbnails': {'avatar_width': 200},
})
db.session.flush()

View file

@ -10,12 +10,10 @@ def test_ctx(
'data_dir': str(tmpdir),
'data_url': 'http://example.com',
'privileges': {
'posts:list': 'regular_user',
'posts:view': 'regular_user',
'posts:list': db.User.RANK_REGULAR,
'posts:view': db.User.RANK_REGULAR,
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -32,7 +30,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.list_api.get(
test_ctx.context_factory(
input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == ''
assert result['page'] == 1
assert result['pageSize'] == 100
@ -41,7 +39,7 @@ def test_retrieving_multiple(test_ctx):
def test_using_special_tokens(
test_ctx, config_injector):
auth_user = test_ctx.user_factory(rank='regular_user')
auth_user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
post1 = test_ctx.post_factory(id=1)
post2 = test_ctx.post_factory(id=2)
post1.favorited_by = [db.PostFavorite(
@ -81,7 +79,7 @@ def test_retrieving_single(test_ctx):
db.session.add(test_ctx.post_factory(id=1))
result = test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 1)
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 1)
assert 'post' in result
assert 'id' in result['post']
assert 'snapshots' in result
@ -91,7 +89,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(posts.PostNotFoundError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-')
def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -8,19 +8,18 @@ from szurubooru.func import posts, tags, snapshots, net
def test_post_updating(
config_injector, context_factory, post_factory, user_factory, fake_datetime):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': {
'posts:edit:tags': 'regular_user',
'posts:edit:content': 'regular_user',
'posts:edit:safety': 'regular_user',
'posts:edit:source': 'regular_user',
'posts:edit:relations': 'regular_user',
'posts:edit:notes': 'regular_user',
'posts:edit:flags': 'regular_user',
'posts:edit:thumbnail': 'regular_user',
'posts:edit:tags': db.User.RANK_REGULAR,
'posts:edit:content': db.User.RANK_REGULAR,
'posts:edit:safety': db.User.RANK_REGULAR,
'posts:edit:source': db.User.RANK_REGULAR,
'posts:edit:relations': db.User.RANK_REGULAR,
'posts:edit:notes': db.User.RANK_REGULAR,
'posts:edit:flags': db.User.RANK_REGULAR,
'posts:edit:thumbnail': db.User.RANK_REGULAR,
},
})
auth_user = user_factory(rank='regular_user')
auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory()
db.session.add(post)
db.session.flush()
@ -76,8 +75,8 @@ def test_post_updating(
def test_uploading_from_url_saves_source(
config_injector, context_factory, post_factory, user_factory):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': {'posts:edit:content': 'regular_user'},
'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {'posts:edit:content': db.User.RANK_REGULAR},
})
post = post_factory()
db.session.add(post)
@ -92,7 +91,7 @@ def test_uploading_from_url_saves_source(
api.PostDetailApi().put(
context_factory(
input={'contentUrl': 'example.com'},
user=user_factory(rank='regular_user')),
user=user_factory(rank=db.User.RANK_REGULAR)),
post.post_id)
net.download.assert_called_once_with('example.com')
posts.update_post_content.assert_called_once_with(post, b'content')
@ -101,10 +100,10 @@ def test_uploading_from_url_saves_source(
def test_uploading_from_url_with_source_specified(
config_injector, context_factory, post_factory, user_factory):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {
'posts:edit:content': 'regular_user',
'posts:edit:source': 'regular_user',
'posts:edit:content': db.User.RANK_REGULAR,
'posts:edit:source': db.User.RANK_REGULAR,
},
})
post = post_factory()
@ -120,7 +119,7 @@ def test_uploading_from_url_with_source_specified(
api.PostDetailApi().put(
context_factory(
input={'contentUrl': 'example.com', 'source': 'example2.com'},
user=user_factory(rank='regular_user')),
user=user_factory(rank=db.User.RANK_REGULAR)),
post.post_id)
net.download.assert_called_once_with('example.com')
posts.update_post_content.assert_called_once_with(post, b'content')
@ -131,7 +130,7 @@ def test_trying_to_update_non_existing(context_factory, user_factory):
api.PostDetailApi().put(
context_factory(
input='whatever',
user=user_factory(rank='regular_user')),
user=user_factory(rank=db.User.RANK_REGULAR)),
1)
@pytest.mark.parametrize('privilege,files,input', [
@ -153,8 +152,8 @@ def test_trying_to_create_without_privileges(
input,
privilege):
config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': {privilege: 'regular_user'},
'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {privilege: db.User.RANK_REGULAR},
})
post = post_factory()
db.session.add(post)

View file

@ -17,11 +17,9 @@ def snapshot_factory():
def test_ctx(context_factory, config_injector, user_factory):
config_injector({
'privileges': {
'snapshots:list': 'regular_user',
'snapshots:list': db.User.RANK_REGULAR,
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -36,7 +34,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.api.get(
test_ctx.context_factory(
input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == ''
assert result['page'] == 1
assert result['pageSize'] == 100

View file

@ -8,8 +8,7 @@ def test_ctx(tmpdir, config_injector, context_factory, user_factory):
config_injector({
'data_dir': str(tmpdir),
'tag_category_name_regex': '^[^!]+$',
'ranks': ['anonymous', 'regular_user'],
'privileges': {'tag_categories:create': 'regular_user'},
'privileges': {'tag_categories:create': db.User.RANK_REGULAR},
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -21,7 +20,7 @@ def test_creating_category(test_ctx):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'name': 'meta', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tagCategory'] == {'name': 'meta', 'color': 'black'}
assert len(result['snapshots']) == 1
category = db.session.query(db.TagCategory).one()
@ -49,7 +48,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input):
test_ctx.api.post(
test_ctx.context_factory(
input=real_input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('field', ['name', 'color'])
def test_trying_to_omit_mandatory_field(test_ctx, field):
@ -62,23 +61,23 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_use_existing_name(test_ctx):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'name': 'meta', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tag_categories.TagCategoryAlreadyExistsError):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'name': 'meta', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tag_categories.TagCategoryAlreadyExistsError):
result = test_ctx.api.post(
test_ctx.context_factory(
input={'name': 'META', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_create_without_privileges(test_ctx):
with pytest.raises(errors.AuthError):

View file

@ -15,9 +15,8 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'privileges': {
'tag_categories:delete': 'regular_user',
'tag_categories:delete': db.User.RANK_REGULAR,
},
'ranks': ['anonymous', 'regular_user'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -33,7 +32,7 @@ def test_deleting(test_ctx):
db.session.commit()
result = test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'category')
assert result == {}
assert db.session.query(db.TagCategory).count() == 1
@ -50,7 +49,7 @@ def test_trying_to_delete_used(test_ctx, tag_factory):
with pytest.raises(tag_categories.TagCategoryIsInUseError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'category')
assert db.session.query(db.TagCategory).count() == 1
@ -60,14 +59,14 @@ def test_trying_to_delete_last(test_ctx, tag_factory):
with pytest.raises(tag_categories.TagCategoryIsInUseError):
result = test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'root')
def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(tag_categories.TagCategoryNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')
def test_trying_to_delete_without_privileges(test_ctx):
db.session.add(test_ctx.tag_category_factory(name='category'))

View file

@ -8,12 +8,10 @@ def test_ctx(
context_factory, config_injector, user_factory, tag_category_factory):
config_injector({
'privileges': {
'tag_categories:list': 'regular_user',
'tag_categories:view': 'regular_user',
'tag_categories:list': db.User.RANK_REGULAR,
'tag_categories:view': db.User.RANK_REGULAR,
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -30,14 +28,14 @@ def test_retrieving_multiple(test_ctx):
])
result = test_ctx.list_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert [cat['name'] for cat in result['results']] == ['c1', 'c2']
def test_retrieving_single(test_ctx):
db.session.add(test_ctx.tag_category_factory(name='cat'))
result = test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'cat')
assert result == {
'tagCategory': {
@ -51,7 +49,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(tag_categories.TagCategoryNotFoundError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-')
def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -13,10 +13,9 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'tag_category_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': {
'tag_categories:edit:name': 'regular_user',
'tag_categories:edit:color': 'regular_user',
'tag_categories:edit:name': db.User.RANK_REGULAR,
'tag_categories:edit:color': db.User.RANK_REGULAR,
},
})
ret = util.dotdict()
@ -36,7 +35,7 @@ def test_simple_updating(test_ctx):
'name': 'changed',
'color': 'white',
},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'name')
assert result['tagCategory'] == {
'name': 'changed',
@ -64,7 +63,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input):
test_ctx.api.put(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'meta')
@pytest.mark.parametrize('field', ['name', 'color'])
@ -79,7 +78,7 @@ def test_omitting_optional_field(test_ctx, field):
result = test_ctx.api.put(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'name')
assert result is not None
@ -88,7 +87,7 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put(
test_ctx.context_factory(
input={'name': ['dummy']},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'bad')
@pytest.mark.parametrize('new_name', ['cat', 'CAT'])
@ -98,7 +97,7 @@ def test_reusing_own_name(test_ctx, new_name):
result = test_ctx.api.put(
test_ctx.context_factory(
input={'name': new_name},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'cat')
assert result['tagCategory']['name'] == new_name
category = tag_categories.get_category_by_name('cat')
@ -114,7 +113,7 @@ def test_trying_to_use_existing_name(test_ctx, dup_name):
test_ctx.api.put(
test_ctx.context_factory(
input={'name': dup_name},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'cat2')
@pytest.mark.parametrize('input', [

View file

@ -15,8 +15,7 @@ def test_ctx(
'data_dir': str(tmpdir),
'tag_name_regex': '^[^!]*$',
'tag_category_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': {'tags:create': 'regular_user'},
'privileges': {'tags:create': db.User.RANK_REGULAR},
})
db.session.add_all([
db.TagCategory(name) for name in ['meta', 'character', 'copyright']])
@ -38,7 +37,7 @@ def test_creating_simple_tags(test_ctx, fake_datetime):
'suggestions': [],
'implications': [],
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag'] == {
'names': ['tag1', 'tag2'],
'category': 'meta',
@ -99,7 +98,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('field', ['implications', 'suggestions'])
def test_omitting_optional_field(test_ctx, field):
@ -113,7 +112,7 @@ def test_omitting_optional_field(test_ctx, field):
result = test_ctx.api.post(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result is not None
def test_duplicating_names(test_ctx):
@ -125,7 +124,7 @@ def test_duplicating_names(test_ctx):
'suggestions': [],
'implications': [],
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag']['names'] == ['tag1']
assert result['tag']['category'] == 'meta'
tag = tags.get_tag_by_name('tag1')
@ -146,7 +145,7 @@ def test_trying_to_use_existing_name(test_ctx):
'suggestions': [],
'implications': [],
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tags.TagAlreadyExistsError):
test_ctx.api.post(
test_ctx.context_factory(
@ -156,7 +155,7 @@ def test_trying_to_use_existing_name(test_ctx):
'suggestions': [],
'implications': [],
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tags.try_get_tag_by_name('unused') is None
def test_creating_new_category(test_ctx):
@ -167,7 +166,7 @@ def test_creating_new_category(test_ctx):
'category': 'new',
'suggestions': [],
'implications': [],
}, user=test_ctx.user_factory(rank='regular_user')))
}, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tag_categories.try_get_category_by_name('new') is not None
@pytest.mark.parametrize('input,expected_suggestions,expected_implications', [
@ -204,7 +203,7 @@ def test_creating_new_suggestions_and_implications(
test_ctx, input, expected_suggestions, expected_implications):
result = test_ctx.api.post(
test_ctx.context_factory(
input=input, user=test_ctx.user_factory(rank='regular_user')))
input=input, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag']['suggestions'] == expected_suggestions
assert result['tag']['implications'] == expected_implications
tag = tags.get_tag_by_name('main')
@ -227,7 +226,7 @@ def test_reusing_suggestions_and_implications(test_ctx):
'suggestions': ['TAG2'],
'implications': ['tag1'],
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
# NOTE: it should export only the first name
assert result['tag']['suggestions'] == ['tag1']
assert result['tag']['implications'] == ['tag1']
@ -254,7 +253,7 @@ def test_tag_trying_to_relate_to_itself(test_ctx, input):
test_ctx.api.post(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tags.try_get_tag_by_name('tag') is None
def test_trying_to_create_tag_without_privileges(test_ctx):

View file

@ -10,9 +10,8 @@ def test_ctx(
config_injector({
'data_dir': str(tmpdir),
'privileges': {
'tags:delete': 'regular_user',
'tags:delete': db.User.RANK_REGULAR,
},
'ranks': ['anonymous', 'regular_user'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -26,7 +25,7 @@ def test_deleting(test_ctx):
db.session.commit()
result = test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag')
assert result == {}
assert db.session.query(db.Tag).count() == 0
@ -41,7 +40,7 @@ def test_trying_to_delete_used(test_ctx, post_factory):
with pytest.raises(tags.TagIsInUseError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag')
assert db.session.query(db.Tag).count() == 1
@ -49,7 +48,7 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')
def test_trying_to_delete_without_privileges(test_ctx):
db.session.add(test_ctx.tag_factory(names=['tag']))

View file

@ -9,9 +9,8 @@ def test_ctx(
tmpdir, config_injector, context_factory, user_factory, tag_factory):
config_injector({
'data_dir': str(tmpdir),
'ranks': ['anonymous', 'regular_user'],
'privileges': {
'tags:merge': 'regular_user',
'tags:merge': db.User.RANK_REGULAR,
},
})
ret = util.dotdict()
@ -33,7 +32,7 @@ def test_merging_without_usages(test_ctx, fake_datetime):
'remove': 'source',
'merge-to': 'target',
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag'] == {
'names': ['target'],
'category': 'meta',
@ -69,7 +68,7 @@ def test_merging_with_usages(test_ctx, fake_datetime, post_factory):
'remove': 'source',
'merge-to': 'target',
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tags.try_get_tag_by_name('source') is None
assert tags.get_tag_by_name('target').post_count == 1
@ -96,7 +95,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
test_ctx.api.post(
test_ctx.context_factory(
input=real_input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize(
'field', ['remove', 'merge-to'])
@ -115,7 +114,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_merge_non_existing(test_ctx):
db.session.add(test_ctx.tag_factory(names=['good'], category_name='meta'))
@ -124,12 +123,12 @@ def test_trying_to_merge_non_existing(test_ctx):
test_ctx.api.post(
test_ctx.context_factory(
input={'remove': 'good', 'merge-to': 'bad'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tags.TagNotFoundError):
test_ctx.api.post(
test_ctx.context_factory(
input={'remove': 'bad', 'merge-to': 'good'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_merge_to_itself(test_ctx):
db.session.add(test_ctx.tag_factory(names=['good'], category_name='meta'))
@ -138,7 +137,7 @@ def test_trying_to_merge_to_itself(test_ctx):
test_ctx.api.post(
test_ctx.context_factory(
input={'remove': 'good', 'merge-to': 'good'},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('input', [
{'names': 'whatever'},

View file

@ -7,12 +7,10 @@ from szurubooru.func import util, tags
def test_ctx(context_factory, config_injector, user_factory, tag_factory):
config_injector({
'privileges': {
'tags:list': 'regular_user',
'tags:view': 'regular_user',
'tags:list': db.User.RANK_REGULAR,
'tags:view': db.User.RANK_REGULAR,
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -29,7 +27,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.list_api.get(
test_ctx.context_factory(
input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == ''
assert result['page'] == 1
assert result['pageSize'] == 100
@ -47,7 +45,7 @@ def test_retrieving_single(test_ctx):
db.session.add(test_ctx.tag_factory(names=['tag']))
result = test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag')
assert result == {
'tag': {
@ -66,7 +64,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-')
def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -16,10 +16,9 @@ def test_ctx(
context_factory, config_injector, user_factory, tag_factory, post_factory):
config_injector({
'privileges': {
'tags:view': 'regular_user',
'tags:view': db.User.RANK_REGULAR,
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -33,7 +32,7 @@ def test_unused(test_ctx):
db.session.add(test_ctx.tag_factory(names=['tag']))
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag')
assert_results(result, {})
def test_used_alone(test_ctx):
@ -43,7 +42,7 @@ def test_used_alone(test_ctx):
db.session.add_all([post, tag])
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag')
assert_results(result, {})
def test_used_with_others(test_ctx):
@ -54,11 +53,11 @@ def test_used_with_others(test_ctx):
db.session.add_all([post, tag1, tag2])
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag1')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag1')
assert_results(result, {'tag2': 1})
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag2')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag2')
assert_results(result, {'tag1': 1})
def test_used_with_multiple_others(test_ctx):
@ -72,22 +71,22 @@ def test_used_with_multiple_others(test_ctx):
db.session.add_all([post1, post2, tag1, tag2, tag3])
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag1')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag1')
assert_results(result, {'tag2': 1, 'tag3': 2})
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag2')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag2')
assert_results(result, {'tag1': 1, 'tag3': 1})
result = test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag3')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag3')
assert_results(result, {'tag1': 2, 'tag2': 1})
def test_trying_to_retrieve_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError):
test_ctx.api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), '-')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), '-')
def test_trying_to_retrieve_without_privileges(test_ctx):
with pytest.raises(errors.AuthError):

View file

@ -15,12 +15,11 @@ def test_ctx(
'data_dir': str(tmpdir),
'tag_name_regex': '^[^!]*$',
'tag_category_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': {
'tags:edit:names': 'regular_user',
'tags:edit:category': 'regular_user',
'tags:edit:suggestions': 'regular_user',
'tags:edit:implications': 'regular_user',
'tags:edit:names': db.User.RANK_REGULAR,
'tags:edit:category': db.User.RANK_REGULAR,
'tags:edit:suggestions': db.User.RANK_REGULAR,
'tags:edit:implications': db.User.RANK_REGULAR,
},
})
db.session.add_all([
@ -44,7 +43,7 @@ def test_simple_updating(test_ctx, fake_datetime):
'names': ['tag3'],
'category': 'character',
},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1')
assert result['tag'] == {
'names': ['tag3'],
@ -86,7 +85,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
test_ctx.api.put(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1')
@pytest.mark.parametrize(
@ -104,7 +103,7 @@ def test_omitting_optional_field(test_ctx, field):
result = test_ctx.api.put(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag')
assert result is not None
@ -113,7 +112,7 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put(
test_ctx.context_factory(
input={'names': ['dummy']},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1')
@pytest.mark.parametrize('dup_name', ['tag1', 'TAG1'])
@ -124,7 +123,7 @@ def test_reusing_own_name(test_ctx, dup_name):
result = test_ctx.api.put(
test_ctx.context_factory(
input={'names': [dup_name, 'tag3']},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1')
assert result['tag']['names'] == ['tag1', 'tag3']
assert tags.try_get_tag_by_name('tag2') is None
@ -139,7 +138,7 @@ def test_duplicating_names(test_ctx):
result = test_ctx.api.put(
test_ctx.context_factory(
input={'names': ['tag3', 'TAG3']},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1')
assert result['tag']['names'] == ['tag3']
assert tags.try_get_tag_by_name('tag1') is None
@ -158,7 +157,7 @@ def test_trying_to_use_existing_name(test_ctx, dup_name):
test_ctx.api.put(
test_ctx.context_factory(
input={'names': [dup_name]},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag3')
@pytest.mark.parametrize('input,expected_suggestions,expected_implications', [
@ -190,7 +189,7 @@ def test_updating_new_suggestions_and_implications(
db.session.commit()
result = test_ctx.api.put(
test_ctx.context_factory(
input=input, user=test_ctx.user_factory(rank='regular_user')),
input=input, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'main')
assert result['tag']['suggestions'] == expected_suggestions
assert result['tag']['implications'] == expected_implications
@ -215,7 +214,7 @@ def test_reusing_suggestions_and_implications(test_ctx):
'suggestions': ['TAG2'],
'implications': ['tag1'],
},
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag4')
# NOTE: it should export only the first name
assert result['tag']['suggestions'] == ['tag1']
@ -244,7 +243,7 @@ def test_trying_to_relate_tag_to_itself(test_ctx, input):
with pytest.raises(tags.InvalidTagRelationError):
test_ctx.api.put(
test_ctx.context_factory(
input=input, user=test_ctx.user_factory(rank='regular_user')),
input=input, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1')
@pytest.mark.parametrize('input', [

View file

@ -14,10 +14,8 @@ def test_ctx(config_injector, context_factory, user_factory):
'secret': '',
'user_name_regex': '[^!]{3,}',
'password_regex': '[^!]{3,}',
'default_rank': 'regular_user',
'default_rank': db.User.RANK_REGULAR,
'thumbnails': {'avatar_width': 200, 'avatar_height': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {},
'privileges': {'users:create': 'anonymous'},
})
ret = util.dotdict()
@ -35,7 +33,7 @@ def test_creating_user(test_ctx, fake_datetime):
'email': 'asd@asd.asd',
'password': 'oks',
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result == {
'user': {
'avatarStyle': 'gravatar',
@ -44,15 +42,14 @@ def test_creating_user(test_ctx, fake_datetime):
'creationTime': datetime.datetime(1969, 2, 12),
'lastLoginTime': None,
'name': 'chewie1',
'rank': 'admin',
'rankName': 'Unknown',
'rank': 'administrator',
'email': 'asd@asd.asd',
}
}
user = users.get_user_by_name('chewie1')
assert user.name == 'chewie1'
assert user.email == 'asd@asd.asd'
assert user.rank == 'admin'
assert user.rank == db.User.RANK_ADMINISTRATOR
assert auth.is_valid_password(user, 'oks') is True
assert auth.is_valid_password(user, 'invalid') is False
@ -73,12 +70,12 @@ def test_first_user_becomes_admin_others_not(test_ctx):
'password': 'sok',
},
user=test_ctx.user_factory(rank='anonymous')))
assert result1['user']['rank'] == 'admin'
assert result2['user']['rank'] == 'regular_user'
assert result1['user']['rank'] == 'administrator'
assert result2['user']['rank'] == 'regular'
first_user = users.get_user_by_name('chewie1')
other_user = users.get_user_by_name('chewie2')
assert first_user.rank == 'admin'
assert other_user.rank == 'regular_user'
assert first_user.rank == db.User.RANK_ADMINISTRATOR
assert other_user.rank == db.User.RANK_REGULAR
def test_first_user_does_not_become_admin_if_they_dont_wish_so(test_ctx):
result = test_ctx.api.post(
@ -87,10 +84,10 @@ def test_first_user_does_not_become_admin_if_they_dont_wish_so(test_ctx):
'name': 'chewie1',
'email': 'asd@asd.asd',
'password': 'oks',
'rank': 'regular_user',
'rank': 'regular',
},
user=test_ctx.user_factory(rank='anonymous')))
assert result['user']['rank'] == 'regular_user'
assert result['user']['rank'] == 'regular'
def test_trying_to_become_someone_else(test_ctx):
test_ctx.api.post(
@ -100,7 +97,7 @@ def test_trying_to_become_someone_else(test_ctx):
'email': 'asd@asd.asd',
'password': 'oks',
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(users.UserAlreadyExistsError):
test_ctx.api.post(
test_ctx.context_factory(
@ -109,7 +106,7 @@ def test_trying_to_become_someone_else(test_ctx):
'email': 'asd@asd.asd',
'password': 'oks',
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(users.UserAlreadyExistsError):
test_ctx.api.post(
test_ctx.context_factory(
@ -118,7 +115,7 @@ def test_trying_to_become_someone_else(test_ctx):
'email': 'asd@asd.asd',
'password': 'oks',
},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('input,expected_exception', [
({'name': None}, users.InvalidUserNameError),
@ -150,7 +147,8 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
test_ctx.api.post(
test_ctx.context_factory(
input=real_input,
user=test_ctx.user_factory(name='u1', rank='admin')))
user=test_ctx.user_factory(
name='u1', rank=db.User.RANK_ADMINISTRATOR)))
@pytest.mark.parametrize('field', ['name', 'password'])
def test_trying_to_omit_mandatory_field(test_ctx, field):
@ -164,7 +162,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post(
test_ctx.context_factory(
input=input,
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('field', ['rank', 'email', 'avatarStyle'])
def test_omitting_optional_field(test_ctx, tmpdir, field):
@ -174,7 +172,7 @@ def test_omitting_optional_field(test_ctx, tmpdir, field):
'name': 'chewie',
'email': 'asd@asd.asd',
'password': 'oks',
'rank': 'mod',
'rank': 'moderator',
'avatarStyle': 'manual',
}
del input[field]
@ -182,33 +180,33 @@ def test_omitting_optional_field(test_ctx, tmpdir, field):
test_ctx.context_factory(
input=input,
files={'avatar': EMPTY_PIXEL},
user=test_ctx.user_factory(rank='mod')))
user=test_ctx.user_factory(rank=db.User.RANK_MODERATOR)))
assert result is not None
def test_mods_trying_to_become_admin(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='mod')
user2 = test_ctx.user_factory(name='u2', rank='mod')
user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2])
context = test_ctx.context_factory(input={
'name': 'chewie',
'email': 'asd@asd.asd',
'password': 'oks',
'rank': 'admin',
'rank': 'administrator',
}, user=user1)
with pytest.raises(errors.AuthError):
test_ctx.api.post(context)
def test_admin_creating_mod_account(test_ctx):
user = test_ctx.user_factory(rank='admin')
user = test_ctx.user_factory(rank=db.User.RANK_ADMINISTRATOR)
db.session.add(user)
context = test_ctx.context_factory(input={
'name': 'chewie',
'email': 'asd@asd.asd',
'password': 'oks',
'rank': 'mod',
'rank': 'moderator',
}, user=user)
result = test_ctx.api.post(context)
assert result['user']['rank'] == 'mod'
assert result['user']['rank'] == 'moderator'
def test_uploading_avatar(test_ctx, tmpdir):
config.config['data_dir'] = str(tmpdir.mkdir('data'))
@ -222,7 +220,7 @@ def test_uploading_avatar(test_ctx, tmpdir):
'avatarStyle': 'manual',
},
files={'avatar': EMPTY_PIXEL},
user=test_ctx.user_factory(rank='mod')))
user=test_ctx.user_factory(rank=db.User.RANK_MODERATOR)))
user = users.get_user_by_name('chewie')
assert user.avatar_style == user.AVATAR_MANUAL
assert response['user']['avatarUrl'] == \

View file

@ -7,10 +7,9 @@ from szurubooru.func import util, users
def test_ctx(config_injector, context_factory, user_factory):
config_injector({
'privileges': {
'users:delete:self': 'regular_user',
'users:delete:any': 'mod',
'users:delete:self': db.User.RANK_REGULAR,
'users:delete:any': db.User.RANK_MODERATOR,
},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
})
ret = util.dotdict()
ret.context_factory = context_factory
@ -19,7 +18,7 @@ def test_ctx(config_injector, context_factory, user_factory):
return ret
def test_deleting_oneself(test_ctx):
user = test_ctx.user_factory(name='u', rank='regular_user')
user = test_ctx.user_factory(name='u', rank=db.User.RANK_REGULAR)
db.session.add(user)
db.session.commit()
result = test_ctx.api.delete(test_ctx.context_factory(user=user), 'u')
@ -27,16 +26,16 @@ def test_deleting_oneself(test_ctx):
assert db.session.query(db.User).count() == 0
def test_deleting_someone_else(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='regular_user')
user2 = test_ctx.user_factory(name='u2', rank='mod')
user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2])
db.session.commit()
test_ctx.api.delete(test_ctx.context_factory(user=user2), 'u1')
assert db.session.query(db.User).count() == 1
def test_trying_to_delete_someone_else_without_privileges(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='regular_user')
user2 = test_ctx.user_factory(name='u2', rank='regular_user')
user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_REGULAR)
db.session.add_all([user1, user2])
db.session.commit()
with pytest.raises(errors.AuthError):
@ -47,4 +46,4 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(users.UserNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad')
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')

View file

@ -6,12 +6,10 @@ 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',
'users:list': db.User.RANK_REGULAR,
'users:view': db.User.RANK_REGULAR,
'users:edit:any:email': db.User.RANK_MODERATOR,
},
'thumbnails': {'avatar_width': 200},
})
@ -23,13 +21,13 @@ def test_ctx(context_factory, config_injector, user_factory):
return ret
def test_retrieving_multiple(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='mod')
user2 = test_ctx.user_factory(name='u2', rank='mod')
user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2])
result = test_ctx.list_api.get(
test_ctx.context_factory(
input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user')))
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == ''
assert result['page'] == 1
assert result['pageSize'] == 100
@ -44,16 +42,15 @@ def test_trying_to_retrieve_multiple_without_privileges(test_ctx):
user=test_ctx.user_factory(rank='anonymous')))
def test_retrieving_single(test_ctx):
db.session.add(test_ctx.user_factory(name='u1', rank='regular_user'))
db.session.add(test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR))
result = test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'u1')
assert result == {
'user': {
'name': 'u1',
'rank': 'regular_user',
'rankName': 'Peasant',
'rank': db.User.RANK_REGULAR,
'creationTime': datetime.datetime(1997, 1, 1),
'lastLoginTime': None,
'avatarStyle': 'gravatar',
@ -66,7 +63,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(users.UserNotFoundError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-')
def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -15,19 +15,17 @@ def test_ctx(config_injector, context_factory, user_factory):
'user_name_regex': '^[^!]{3,}$',
'password_regex': '^[^!]{3,}$',
'thumbnails': {'avatar_width': 200, 'avatar_height': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {},
'privileges': {
'users:edit:self:name': 'regular_user',
'users:edit:self:pass': 'regular_user',
'users:edit:self:email': 'regular_user',
'users:edit:self:rank': 'mod',
'users:edit:self:avatar': 'mod',
'users:edit:any:name': 'mod',
'users:edit:any:pass': 'mod',
'users:edit:any:email': 'mod',
'users:edit:any:rank': 'admin',
'users:edit:any:avatar': 'admin',
'users:edit:self:name': db.User.RANK_REGULAR,
'users:edit:self:pass': db.User.RANK_REGULAR,
'users:edit:self:email': db.User.RANK_REGULAR,
'users:edit:self:rank': db.User.RANK_MODERATOR,
'users:edit:self:avatar': db.User.RANK_MODERATOR,
'users:edit:any:name': db.User.RANK_MODERATOR,
'users:edit:any:pass': db.User.RANK_MODERATOR,
'users:edit:any:email': db.User.RANK_MODERATOR,
'users:edit:any:rank': db.User.RANK_ADMINISTRATOR,
'users:edit:any:avatar': db.User.RANK_ADMINISTRATOR,
},
})
ret = util.dotdict()
@ -37,7 +35,7 @@ def test_ctx(config_injector, context_factory, user_factory):
return ret
def test_updating_user(test_ctx):
user = test_ctx.user_factory(name='u1', rank='admin')
user = test_ctx.user_factory(name='u1', rank=db.User.RANK_ADMINISTRATOR)
db.session.add(user)
result = test_ctx.api.put(
test_ctx.context_factory(
@ -45,7 +43,7 @@ def test_updating_user(test_ctx):
'name': 'chewie',
'email': 'asd@asd.asd',
'password': 'oks',
'rank': 'mod',
'rank': 'moderator',
'avatarStyle': 'gravatar',
},
user=user),
@ -59,14 +57,13 @@ def test_updating_user(test_ctx):
'lastLoginTime': None,
'email': 'asd@asd.asd',
'name': 'chewie',
'rank': 'mod',
'rankName': 'Unknown',
'rank': 'moderator',
}
}
user = users.get_user_by_name('chewie')
assert user.name == 'chewie'
assert user.email == 'asd@asd.asd'
assert user.rank == 'mod'
assert user.rank == db.User.RANK_MODERATOR
assert user.avatar_style == user.AVATAR_GRAVATAR
assert auth.is_valid_password(user, 'oks') is True
assert auth.is_valid_password(user, 'invalid') is False
@ -90,7 +87,7 @@ def test_updating_user(test_ctx):
({'avatarStyle': 'manual'}, users.InvalidAvatarError), # missing file
])
def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
user = test_ctx.user_factory(name='u1', rank='admin')
user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user)
with pytest.raises(expected_exception):
test_ctx.api.put(
@ -101,13 +98,13 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
def test_omitting_optional_field(test_ctx, tmpdir, field):
config.config['data_dir'] = str(tmpdir.mkdir('data'))
config.config['data_url'] = 'http://example.com/data/'
user = test_ctx.user_factory(name='u1', rank='admin')
user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user)
input = {
'name': 'chewie',
'email': 'asd@asd.asd',
'password': 'oks',
'rank': 'mod',
'rank': 'moderator',
'avatarStyle': 'gravatar',
}
del input[field]
@ -120,13 +117,13 @@ def test_omitting_optional_field(test_ctx, tmpdir, field):
assert result is not None
def test_trying_to_update_non_existing(test_ctx):
user = test_ctx.user_factory(name='u1', rank='admin')
user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user)
with pytest.raises(users.UserNotFoundError):
test_ctx.api.put(test_ctx.context_factory(user=user), 'u2')
def test_removing_email(test_ctx):
user = test_ctx.user_factory(name='u1', rank='admin')
user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user)
test_ctx.api.put(
test_ctx.context_factory(input={'email': ''}, user=user), 'u1')
@ -140,16 +137,16 @@ def test_removing_email(test_ctx):
{'avatarStyle': 'whatever'},
])
def test_trying_to_update_someone_else(test_ctx, input):
user1 = test_ctx.user_factory(name='u1', rank='regular_user')
user2 = test_ctx.user_factory(name='u2', rank='regular_user')
user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_REGULAR)
db.session.add_all([user1, user2])
with pytest.raises(errors.AuthError):
test_ctx.api.put(
test_ctx.context_factory(input=input, user=user1), user2.name)
def test_trying_to_become_someone_else(test_ctx):
user1 = test_ctx.user_factory(name='me', rank='regular_user')
user2 = test_ctx.user_factory(name='her', rank='regular_user')
user1 = test_ctx.user_factory(name='me', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='her', rank=db.User.RANK_REGULAR)
db.session.add_all([user1, user2])
with pytest.raises(users.UserAlreadyExistsError):
test_ctx.api.put(
@ -160,10 +157,10 @@ def test_trying_to_become_someone_else(test_ctx):
test_ctx.context_factory(input={'name': 'HER'}, user=user1), 'me')
def test_mods_trying_to_become_admin(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='mod')
user2 = test_ctx.user_factory(name='u2', rank='mod')
user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2])
context = test_ctx.context_factory(input={'rank': 'admin'}, user=user1)
context = test_ctx.context_factory(input={'rank': 'administrator'}, user=user1)
with pytest.raises(errors.AuthError):
test_ctx.api.put(context, user1.name)
with pytest.raises(errors.AuthError):
@ -172,7 +169,7 @@ def test_mods_trying_to_become_admin(test_ctx):
def test_uploading_avatar(test_ctx, tmpdir):
config.config['data_dir'] = str(tmpdir.mkdir('data'))
config.config['data_url'] = 'http://example.com/data/'
user = test_ctx.user_factory(name='u1', rank='mod')
user = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
db.session.add(user)
response = test_ctx.api.put(
test_ctx.context_factory(

View file

@ -90,7 +90,7 @@ def config_injector():
@pytest.fixture
def user_factory():
def factory(name=None, rank='regular_user', email='dummy'):
def factory(name=None, rank=db.User.RANK_REGULAR, email='dummy'):
user = db.User()
user.name = name or get_unique_name()
user.password_salt = 'dummy'