Esempio n. 1
0
def _get_user(ctx: rest.Context, bump_login: bool) -> Optional[model.User]:
    if not ctx.has_header('Authorization'):
        return None

    auth_token = None

    try:
        auth_type, credentials = ctx.get_header('Authorization').split(' ', 1)
        if auth_type.lower() == 'basic':
            username, password = base64.decodebytes(
                credentials.encode('ascii')).decode('utf8').split(':', 1)
            auth_user = _authenticate_basic_auth(username, password)
        elif auth_type.lower() == 'token':
            username, token = base64.decodebytes(
                credentials.encode('ascii')).decode('utf8').split(':', 1)
            auth_user, auth_token = _authenticate_token(username, token)
        else:
            raise HttpBadRequest(
                'ValidationError',
                'Only basic or token HTTP authentication is supported.')
    except ValueError as err:
        msg = (
            'Authorization header values are not properly formed. '
            'Supplied header {0}. Got error: {1}')
        raise HttpBadRequest(
            'ValidationError',
            msg.format(ctx.get_header('Authorization'), str(err)))

    if bump_login and auth_user.user_id:
        users.bump_user_login_time(auth_user)
        if auth_token is not None:
            user_tokens.bump_usage_time(auth_token)
        ctx.session.commit()

    return auth_user
Esempio n. 2
0
def _get_user(ctx: rest.Context, bump_login: bool) -> Optional[model.User]:
    if not ctx.has_header('Authorization'):
        return None

    auth_token = None

    try:
        auth_type, credentials = ctx.get_header('Authorization').split(' ', 1)
        if auth_type.lower() == 'basic':
            username, password = base64.decodebytes(
                credentials.encode('ascii')).decode('utf8').split(':', 1)
            auth_user = _authenticate_basic_auth(username, password)
        elif auth_type.lower() == 'token':
            username, token = base64.decodebytes(
                credentials.encode('ascii')).decode('utf8').split(':', 1)
            auth_user, auth_token = _authenticate_token(username, token)
        else:
            raise HttpBadRequest('ValidationError', '기본 및 토큰 HTTP 인증만을 지원합니다.')
    except ValueError as err:
        msg = ('인증 헤더 값이 적절한 형식이 아닙니다. ' '전달된 헤더 {0}. 오류: {1}')
        raise HttpBadRequest(
            'ValidationError',
            msg.format(ctx.get_header('Authorization'), str(err)))

    if bump_login and auth_user.user_id:
        users.bump_user_login_time(auth_user)
        if auth_token is not None:
            user_tokens.bump_usage_time(auth_token)
        ctx.session.commit()

    return auth_user
Esempio n. 3
0
def update_tag(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    tag = _get_tag(params)
    versions.verify_version(tag, ctx)
    versions.bump_version(tag)
    if ctx.has_param('names'):
        auth.verify_privilege(ctx.user, 'tags:edit:names')
        tags.update_tag_names(tag, ctx.get_param_as_string_list('names'))
    if ctx.has_param('category'):
        auth.verify_privilege(ctx.user, 'tags:edit:category')
        tags.update_tag_category_name(
            tag, ctx.get_param_as_string('category'))
    if ctx.has_param('description'):
        auth.verify_privilege(ctx.user, 'tags:edit:description')
        tags.update_tag_description(
            tag, ctx.get_param_as_string('description'))
    if ctx.has_param('suggestions'):
        auth.verify_privilege(ctx.user, 'tags:edit:suggestions')
        suggestions = ctx.get_param_as_string_list('suggestions')
        _create_if_needed(suggestions, ctx.user)
        tags.update_tag_suggestions(tag, suggestions)
    if ctx.has_param('implications'):
        auth.verify_privilege(ctx.user, 'tags:edit:implications')
        implications = ctx.get_param_as_string_list('implications')
        _create_if_needed(implications, ctx.user)
        tags.update_tag_implications(tag, implications)
    tag.last_edit_time = datetime.utcnow()
    ctx.session.flush()
    snapshots.modify(tag, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, tag)
Esempio n. 4
0
def update_tag(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    tag = _get_tag(params)
    versions.verify_version(tag, ctx)
    versions.bump_version(tag)
    if ctx.has_param("names"):
        auth.verify_privilege(ctx.user, "tags:edit:names")
        tags.update_tag_names(tag, ctx.get_param_as_string_list("names"))
    if ctx.has_param("category"):
        auth.verify_privilege(ctx.user, "tags:edit:category")
        tags.update_tag_category_name(tag, ctx.get_param_as_string("category"))
    if ctx.has_param("description"):
        auth.verify_privilege(ctx.user, "tags:edit:description")
        tags.update_tag_description(tag,
                                    ctx.get_param_as_string("description"))
    if ctx.has_param("suggestions"):
        auth.verify_privilege(ctx.user, "tags:edit:suggestions")
        suggestions = ctx.get_param_as_string_list("suggestions")
        _create_if_needed(suggestions, ctx.user)
        tags.update_tag_suggestions(tag, suggestions)
    if ctx.has_param("implications"):
        auth.verify_privilege(ctx.user, "tags:edit:implications")
        implications = ctx.get_param_as_string_list("implications")
        _create_if_needed(implications, ctx.user)
        tags.update_tag_implications(tag, implications)
    tag.last_edit_time = datetime.utcnow()
    ctx.session.flush()
    snapshots.modify(tag, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, tag)
Esempio n. 5
0
def process_request(ctx: rest.Context) -> None:
    ''' Bind the user to request. Update last login time if needed. '''
    auth_user = _get_user(ctx)
    if auth_user:
        ctx.user = auth_user
    if ctx.get_param_as_bool('bump-login', default=False) and ctx.user.user_id:
        users.bump_user_login_time(ctx.user)
        ctx.session.commit()
Esempio n. 6
0
def create_comment(ctx: rest.Context,
                   _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'comments:create')
    text = ctx.get_param_as_string('text')
    post_id = ctx.get_param_as_int('postId')
    post = posts.get_post_by_id(post_id)
    comment = comments.create_comment(ctx.user, post, text)
    ctx.session.add(comment)
    ctx.session.commit()
    return _serialize(ctx, comment)
Esempio n. 7
0
def create_comment(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'comments:create')
    text = ctx.get_param_as_string('text')
    post_id = ctx.get_param_as_int('postId')
    post = posts.get_post_by_id(post_id)
    comment = comments.create_comment(ctx.user, post, text)
    ctx.session.add(comment)
    ctx.session.commit()
    return _serialize(ctx, comment)
Esempio n. 8
0
def create_pool_category(ctx: rest.Context,
                         _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, "pool_categories:create")
    name = ctx.get_param_as_string("name")
    color = ctx.get_param_as_string("color")
    category = pool_categories.create_category(name, color)
    ctx.session.add(category)
    ctx.session.flush()
    snapshots.create(category, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, category)
Esempio n. 9
0
def create_tag_category(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'tag_categories:create')
    name = ctx.get_param_as_string('name')
    color = ctx.get_param_as_string('color')
    category = tag_categories.create_category(name, color)
    ctx.session.add(category)
    ctx.session.flush()
    snapshots.create(category, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, category)
Esempio n. 10
0
def create_tag_category(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'tag_categories:create')
    name = ctx.get_param_as_string('name')
    color = ctx.get_param_as_string('color')
    category = tag_categories.create_category(name, color)
    ctx.session.add(category)
    ctx.session.flush()
    snapshots.create(category, ctx.user)
    ctx.session.commit()
    tags.export_to_json()
    return _serialize(ctx, category)
Esempio n. 11
0
def merge_tags(ctx: rest.Context,
               _params: Dict[str, str] = {}) -> rest.Response:
    source_tag_name = ctx.get_param_as_string("remove")
    target_tag_name = ctx.get_param_as_string("mergeTo")
    source_tag = tags.get_tag_by_name(source_tag_name)
    target_tag = tags.get_tag_by_name(target_tag_name)
    versions.verify_version(source_tag, ctx, "removeVersion")
    versions.verify_version(target_tag, ctx, "mergeToVersion")
    versions.bump_version(target_tag)
    auth.verify_privilege(ctx.user, "tags:merge")
    tags.merge_tags(source_tag, target_tag)
    snapshots.merge(source_tag, target_tag, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, target_tag)
Esempio n. 12
0
def merge_tags(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    source_tag_name = ctx.get_param_as_string('remove')
    target_tag_name = ctx.get_param_as_string('mergeTo')
    source_tag = tags.get_tag_by_name(source_tag_name)
    target_tag = tags.get_tag_by_name(target_tag_name)
    versions.verify_version(source_tag, ctx, 'removeVersion')
    versions.verify_version(target_tag, ctx, 'mergeToVersion')
    versions.bump_version(target_tag)
    auth.verify_privilege(ctx.user, 'tags:merge')
    tags.merge_tags(source_tag, target_tag)
    snapshots.merge(source_tag, target_tag, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, target_tag)
Esempio n. 13
0
def merge_pools(ctx: rest.Context,
                _params: Dict[str, str] = {}) -> rest.Response:
    source_pool_id = ctx.get_param_as_string("remove")
    target_pool_id = ctx.get_param_as_string("mergeTo")
    source_pool = pools.get_pool_by_id(source_pool_id)
    target_pool = pools.get_pool_by_id(target_pool_id)
    versions.verify_version(source_pool, ctx, "removeVersion")
    versions.verify_version(target_pool, ctx, "mergeToVersion")
    versions.bump_version(target_pool)
    auth.verify_privilege(ctx.user, "pools:merge")
    pools.merge_pools(source_pool, target_pool)
    snapshots.merge(source_pool, target_pool, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, target_pool)
Esempio n. 14
0
def merge_posts(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    source_post_id = ctx.get_param_as_int('remove')
    target_post_id = ctx.get_param_as_int('mergeTo')
    source_post = posts.get_post_by_id(source_post_id)
    target_post = posts.get_post_by_id(target_post_id)
    replace_content = ctx.get_param_as_bool('replaceContent')
    versions.verify_version(source_post, ctx, 'removeVersion')
    versions.verify_version(target_post, ctx, 'mergeToVersion')
    versions.bump_version(target_post)
    auth.verify_privilege(ctx.user, 'posts:merge')
    posts.merge_posts(source_post, target_post, replace_content)
    snapshots.merge(source_post, target_post, ctx.user)
    ctx.session.commit()
    return _serialize_post(ctx, target_post)
Esempio n. 15
0
 def execute_and_serialize(
         self, ctx: rest.Context,
         serializer: Callable[[model.Base],
                              rest.Response]) -> rest.Response:
     query = ctx.get_param_as_string('query', default='')
     offset = ctx.get_param_as_int('offset', default=0, min=0)
     limit = ctx.get_param_as_int('limit', default=100, min=1, max=100)
     count, entities = self.execute(query, offset, limit)
     return {
         'query': query,
         'offset': offset,
         'limit': limit,
         'total': count,
         'results': list([serializer(entity) for entity in entities]),
     }
Esempio n. 16
0
def merge_posts(ctx: rest.Context,
                _params: Dict[str, str] = {}) -> rest.Response:
    source_post_id = ctx.get_param_as_int('remove')
    target_post_id = ctx.get_param_as_int('mergeTo')
    source_post = posts.get_post_by_id(source_post_id)
    target_post = posts.get_post_by_id(target_post_id)
    replace_content = ctx.get_param_as_bool('replaceContent')
    versions.verify_version(source_post, ctx, 'removeVersion')
    versions.verify_version(target_post, ctx, 'mergeToVersion')
    versions.bump_version(target_post)
    auth.verify_privilege(ctx.user, 'posts:merge')
    posts.merge_posts(source_post, target_post, replace_content)
    snapshots.merge(source_post, target_post, ctx.user)
    ctx.session.commit()
    return _serialize_post(ctx, target_post)
Esempio n. 17
0
 def execute_and_serialize(
     self,
     ctx: rest.Context,
     serializer: Callable[[model.Base], rest.Response]
 ) -> rest.Response:
     query = ctx.get_param_as_string('query', default='')
     offset = ctx.get_param_as_int('offset', default=0, min=0)
     limit = ctx.get_param_as_int('limit', default=100, min=1, max=100)
     count, entities = self.execute(query, offset, limit)
     return {
         'query': query,
         'offset': offset,
         'limit': limit,
         'total': count,
         'results': list([serializer(entity) for entity in entities]),
     }
Esempio n. 18
0
def set_post_score(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    auth.verify_privilege(ctx.user, 'posts:score')
    post = _get_post(params)
    score = ctx.get_param_as_int('score')
    scores.set_score(post, ctx.user, score)
    ctx.session.commit()
    return _serialize_post(ctx, post)
Esempio n. 19
0
def set_post_score(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    auth.verify_privilege(ctx.user, 'posts:score')
    post = _get_post(params)
    score = ctx.get_param_as_int('score')
    scores.set_score(post, ctx.user, score)
    ctx.session.commit()
    return _serialize_post(ctx, post)
Esempio n. 20
0
 def execute_and_serialize(
     self,
     ctx: rest.Context,
     serializer: Callable[[model.Base], rest.Response],
 ) -> rest.Response:
     query = ctx.get_param_as_string("query", default="")
     offset = ctx.get_param_as_int("offset", default=0, min=0)
     limit = ctx.get_param_as_int("limit", default=100, min=1, max=100)
     count, entities = self.execute(query, offset, limit)
     return {
         "query": query,
         "offset": offset,
         "limit": limit,
         "total": count,
         "results": list([serializer(entity) for entity in entities]),
     }
Esempio n. 21
0
def verify_version(entity: model.Base,
                   context: rest.Context,
                   field_name: str = 'version') -> None:
    actual_version = context.get_param_as_int(field_name)
    expected_version = entity.version
    if actual_version != expected_version:
        raise errors.IntegrityError('다른 누군가 이미 수정하고 있습니다. ' + '다시 시도해 보세요.')
Esempio n. 22
0
def create_user_token(ctx: rest.Context,
                      params: Dict[str, str] = {}) -> rest.Response:
    user = users.get_user_by_name(params['user_name'])
    infix = 'self' if ctx.user.user_id == user.user_id else 'any'
    auth.verify_privilege(ctx.user, 'user_tokens:create:%s' % infix)
    enabled = ctx.get_param_as_bool('enabled', True)
    user_token = user_tokens.create_user_token(user, enabled)
    if ctx.has_param('note'):
        note = ctx.get_param_as_string('note')
        user_tokens.update_user_token_note(user_token, note)
    if ctx.has_param('expirationTime'):
        expiration_time = ctx.get_param_as_string('expirationTime')
        user_tokens.update_user_token_expiration_time(user_token,
                                                      expiration_time)
    ctx.session.add(user_token)
    ctx.session.commit()
    return _serialize(ctx, user_token)
Esempio n. 23
0
def create_pool(ctx: rest.Context,
                _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, "pools:create")

    names = ctx.get_param_as_string_list("names")
    category = ctx.get_param_as_string("category")
    description = ctx.get_param_as_string("description", default="")
    posts = ctx.get_param_as_int_list("posts", default=[])

    pool = pools.create_pool(names, category, posts)
    pool.last_edit_time = datetime.utcnow()
    pools.update_pool_description(pool, description)
    ctx.session.add(pool)
    ctx.session.flush()
    snapshots.create(pool, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, pool)
Esempio n. 24
0
def create_user_token(
        ctx: rest.Context, params: Dict[str, str] = {}) -> rest.Response:
    user = users.get_user_by_name(params['user_name'])
    infix = 'self' if ctx.user.user_id == user.user_id else 'any'
    auth.verify_privilege(ctx.user, 'user_tokens:create:%s' % infix)
    enabled = ctx.get_param_as_bool('enabled', True)
    user_token = user_tokens.create_user_token(user, enabled)
    if ctx.has_param('note'):
        note = ctx.get_param_as_string('note')
        user_tokens.update_user_token_note(user_token, note)
    if ctx.has_param('expirationTime'):
        expiration_time = ctx.get_param_as_string('expirationTime')
        user_tokens.update_user_token_expiration_time(
            user_token, expiration_time)
    ctx.session.add(user_token)
    ctx.session.commit()
    return _serialize(ctx, user_token)
Esempio n. 25
0
def set_comment_score(ctx: rest.Context, params: Dict[str,
                                                      str]) -> rest.Response:
    auth.verify_privilege(ctx.user, "comments:score")
    score = ctx.get_param_as_int("score")
    comment = _get_comment(params)
    scores.set_score(comment, ctx.user, score)
    ctx.session.commit()
    return _serialize(ctx, comment)
Esempio n. 26
0
def create_user_token(ctx: rest.Context,
                      params: Dict[str, str] = {}) -> rest.Response:
    user = users.get_user_by_name(params["user_name"])
    infix = "self" if ctx.user.user_id == user.user_id else "any"
    auth.verify_privilege(ctx.user, "user_tokens:create:%s" % infix)
    enabled = ctx.get_param_as_bool("enabled", True)
    user_token = user_tokens.create_user_token(user, enabled)
    if ctx.has_param("note"):
        note = ctx.get_param_as_string("note")
        user_tokens.update_user_token_note(user_token, note)
    if ctx.has_param("expirationTime"):
        expiration_time = ctx.get_param_as_string("expirationTime")
        user_tokens.update_user_token_expiration_time(user_token,
                                                      expiration_time)
    ctx.session.add(user_token)
    ctx.session.commit()
    return _serialize(ctx, user_token)
Esempio n. 27
0
def verify_version(entity: model.Base,
                   context: rest.Context,
                   field_name: str = 'version') -> None:
    actual_version = context.get_param_as_int(field_name)
    expected_version = entity.version
    if actual_version != expected_version:
        raise errors.IntegrityError(
            'Someone else modified this in the meantime. ' +
            'Please try again.')
Esempio n. 28
0
 def execute_and_serialize(
         self, ctx: rest.Context,
         serializer: Callable[[model.Base],
                              rest.Response]) -> rest.Response:
     query = ctx.get_param_as_string('query', default='')
     page = ctx.get_param_as_int('page', default=1, min=1)
     page_size = ctx.get_param_as_int('pageSize',
                                      default=100,
                                      min=1,
                                      max=100)
     count, entities = self.execute(query, page, page_size)
     return {
         'query': query,
         'page': page,
         'pageSize': page_size,
         'total': count,
         'results': [serializer(entity) for entity in entities],
     }
Esempio n. 29
0
def update_tag_category(
        ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    category = tag_categories.get_category_by_name(
        params['category_name'], lock=True)
    versions.verify_version(category, ctx)
    versions.bump_version(category)
    if ctx.has_param('name'):
        auth.verify_privilege(ctx.user, 'tag_categories:edit:name')
        tag_categories.update_category_name(
            category, ctx.get_param_as_string('name'))
    if ctx.has_param('color'):
        auth.verify_privilege(ctx.user, 'tag_categories:edit:color')
        tag_categories.update_category_color(
            category, ctx.get_param_as_string('color'))
    ctx.session.flush()
    snapshots.modify(category, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, category)
Esempio n. 30
0
def update_pool_category(ctx: rest.Context,
                         params: Dict[str, str]) -> rest.Response:
    category = pool_categories.get_category_by_name(params["category_name"],
                                                    lock=True)
    versions.verify_version(category, ctx)
    versions.bump_version(category)
    if ctx.has_param("name"):
        auth.verify_privilege(ctx.user, "pool_categories:edit:name")
        pool_categories.update_category_name(category,
                                             ctx.get_param_as_string("name"))
    if ctx.has_param("color"):
        auth.verify_privilege(ctx.user, "pool_categories:edit:color")
        pool_categories.update_category_color(category,
                                              ctx.get_param_as_string("color"))
    ctx.session.flush()
    snapshots.modify(category, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, category)
Esempio n. 31
0
def create_temporary_file(ctx: rest.Context,
                          _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'uploads:create')
    content = ctx.get_file('content',
                           allow_tokens=False,
                           use_video_downloader=auth.has_privilege(
                               ctx.user, 'uploads:use_downloader'))
    token = file_uploads.save(content)
    return {'token': token}
Esempio n. 32
0
def _get_user(ctx: rest.Context, bump_login: bool) -> Optional[model.User]:
    if not ctx.has_header("Authorization"):
        return None

    auth_token = None

    try:
        auth_type, credentials = ctx.get_header("Authorization").split(" ", 1)
        if auth_type.lower() == "basic":
            username, password = (
                base64.decodebytes(credentials.encode("ascii"))
                .decode("utf8")
                .split(":", 1)
            )
            auth_user = _authenticate_basic_auth(username, password)
        elif auth_type.lower() == "token":
            username, token = (
                base64.decodebytes(credentials.encode("ascii"))
                .decode("utf8")
                .split(":", 1)
            )
            auth_user, auth_token = _authenticate_token(username, token)
        else:
            raise HttpBadRequest(
                "ValidationError",
                "Only basic or token HTTP authentication is supported.",
            )
    except ValueError as err:
        msg = (
            "Authorization header values are not properly formed. "
            "Supplied header {0}. Got error: {1}"
        )
        raise HttpBadRequest(
            "ValidationError",
            msg.format(ctx.get_header("Authorization"), str(err)),
        )

    if bump_login and auth_user.user_id:
        users.bump_user_login_time(auth_user)
        if auth_token is not None:
            user_tokens.bump_usage_time(auth_token)
        ctx.session.commit()

    return auth_user
Esempio n. 33
0
def verify_version(
        entity: model.Base,
        context: rest.Context,
        field_name: str = 'version') -> None:
    actual_version = context.get_param_as_int(field_name)
    expected_version = entity.version
    if actual_version != expected_version:
        raise errors.IntegrityError(
            'Someone else modified this in the meantime. ' +
            'Please try again.')
Esempio n. 34
0
def update_tag_category(
        ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    category = tag_categories.get_category_by_name(
        params['category_name'], lock=True)
    versions.verify_version(category, ctx)
    versions.bump_version(category)
    if ctx.has_param('name'):
        auth.verify_privilege(ctx.user, 'tag_categories:edit:name')
        tag_categories.update_category_name(
            category, ctx.get_param_as_string('name'))
    if ctx.has_param('color'):
        auth.verify_privilege(ctx.user, 'tag_categories:edit:color')
        tag_categories.update_category_color(
            category, ctx.get_param_as_string('color'))
    ctx.session.flush()
    snapshots.modify(category, ctx.user)
    ctx.session.commit()
    tags.export_to_json()
    return _serialize(ctx, category)
Esempio n. 35
0
 def get_around_and_serialize(
         self, ctx: rest.Context, entity_id: int,
         serializer: Callable[[model.Base],
                              rest.Response]) -> rest.Response:
     entities = self.get_around(
         ctx.get_param_as_string('query', default=''), entity_id)
     return {
         'prev': serializer(entities[0]),
         'next': serializer(entities[1]),
     }
Esempio n. 36
0
def _get_user(ctx: rest.Context) -> Optional[model.User]:
    if not ctx.has_header('Authorization'):
        return None

    try:
        auth_type, credentials = ctx.get_header('Authorization').split(' ', 1)
        if auth_type.lower() != 'basic':
            raise HttpBadRequest(
                'ValidationError',
                'Only basic HTTP authentication is supported.')
        username, password = base64.decodebytes(
            credentials.encode('ascii')).decode('utf8').split(':')
        return _authenticate(username, password)
    except ValueError as err:
        msg = ('Basic authentication header value are not properly formed. '
               'Supplied header {0}. Got error: {1}')
        raise HttpBadRequest(
            'ValidationError',
            msg.format(ctx.get_header('Authorization'), str(err)))
Esempio n. 37
0
def update_comment(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    comment = _get_comment(params)
    versions.verify_version(comment, ctx)
    versions.bump_version(comment)
    infix = 'own' if ctx.user.user_id == comment.user_id else 'any'
    text = ctx.get_param_as_string('text')
    auth.verify_privilege(ctx.user, 'comments:edit:%s' % infix)
    comments.update_comment_text(comment, text)
    comment.last_edit_time = datetime.utcnow()
    ctx.session.commit()
    return _serialize(ctx, comment)
Esempio n. 38
0
def create_tag(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'tags:create')

    names = ctx.get_param_as_string_list('names')
    category = ctx.get_param_as_string('category')
    description = ctx.get_param_as_string('description', default='')
    suggestions = ctx.get_param_as_string_list('suggestions', default=[])
    implications = ctx.get_param_as_string_list('implications', default=[])

    _create_if_needed(suggestions, ctx.user)
    _create_if_needed(implications, ctx.user)

    tag = tags.create_tag(names, category, suggestions, implications)
    tags.update_tag_description(tag, description)
    ctx.session.add(tag)
    ctx.session.flush()
    snapshots.create(tag, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, tag)
Esempio n. 39
0
def update_comment(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    comment = _get_comment(params)
    versions.verify_version(comment, ctx)
    versions.bump_version(comment)
    infix = 'own' if ctx.user.user_id == comment.user_id else 'any'
    text = ctx.get_param_as_string('text')
    auth.verify_privilege(ctx.user, 'comments:edit:%s' % infix)
    comments.update_comment_text(comment, text)
    comment.last_edit_time = datetime.utcnow()
    ctx.session.commit()
    return _serialize(ctx, comment)
Esempio n. 40
0
def create_tag(ctx: rest.Context,
               _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, "tags:create")

    names = ctx.get_param_as_string_list("names")
    category = ctx.get_param_as_string("category")
    description = ctx.get_param_as_string("description", default="")
    suggestions = ctx.get_param_as_string_list("suggestions", default=[])
    implications = ctx.get_param_as_string_list("implications", default=[])

    _create_if_needed(suggestions, ctx.user)
    _create_if_needed(implications, ctx.user)

    tag = tags.create_tag(names, category, suggestions, implications)
    tags.update_tag_description(tag, description)
    ctx.session.add(tag)
    ctx.session.flush()
    snapshots.create(tag, ctx.user)
    ctx.session.commit()
    return _serialize(ctx, tag)
Esempio n. 41
0
def finish_password_reset(ctx: rest.Context,
                          params: Dict[str, str]) -> rest.Response:
    user_name = params['user_name']
    user = users.get_user_by_name_or_email(user_name)
    good_token = auth.generate_authentication_token(user)
    token = ctx.get_param_as_string('token')
    if _hash(token) != _hash(good_token):
        raise errors.ValidationError('Invalid password reset token.')
    new_password = users.reset_user_password(user)
    versions.bump_version(user)
    ctx.session.commit()
    return {'password': new_password}
Esempio n. 42
0
def set_featured_post(ctx: rest.Context,
                      _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'posts:feature')
    post_id = ctx.get_param_as_int('id')
    post = posts.get_post_by_id(post_id)
    featured_post = posts.try_get_featured_post()
    if featured_post and featured_post.post_id == post.post_id:
        raise posts.PostAlreadyFeaturedError('짤 %r 는 이미 대문짤임.' % post_id)
    posts.feature_post(post, ctx.user)
    snapshots.modify(post, ctx.user)
    ctx.session.commit()
    return _serialize_post(ctx, post)
Esempio n. 43
0
 def get_around_and_serialize(
     self,
     ctx: rest.Context,
     entity_id: int,
     serializer: Callable[[model.Base], rest.Response]
 ) -> rest.Response:
     entities = self.get_around(
         ctx.get_param_as_string('query', default=''), entity_id)
     return {
         'prev': serializer(entities[0]),
         'next': serializer(entities[1]),
     }
Esempio n. 44
0
 def get_around_and_serialize(
     self,
     ctx: rest.Context,
     entity_id: int,
     serializer: Callable[[model.Base], rest.Response],
 ) -> rest.Response:
     entities = self.get_around(
         ctx.get_param_as_string("query", default=""), entity_id)
     return {
         "prev": serializer(entities[0]),
         "next": serializer(entities[1]),
     }
Esempio n. 45
0
def finish_password_reset(
        ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    user_name = params['user_name']
    user = users.get_user_by_name_or_email(user_name)
    good_token = auth.generate_authentication_token(user)
    token = ctx.get_param_as_string('token')
    if _hash(token) != _hash(good_token):
        raise errors.ValidationError('Invalid password reset token.')
    new_password = users.reset_user_password(user)
    versions.bump_version(user)
    ctx.session.commit()
    return {'password': new_password}
Esempio n. 46
0
def set_featured_post(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'posts:feature')
    post_id = ctx.get_param_as_int('id')
    post = posts.get_post_by_id(post_id)
    featured_post = posts.try_get_featured_post()
    if featured_post and featured_post.post_id == post.post_id:
        raise posts.PostAlreadyFeaturedError(
            'Post %r is already featured.' % post_id)
    posts.feature_post(post, ctx.user)
    snapshots.modify(post, ctx.user)
    ctx.session.commit()
    return _serialize_post(ctx, post)
Esempio n. 47
0
def create_user(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    if ctx.user.user_id is None:
        auth.verify_privilege(ctx.user, 'users:create:self')
    else:
        auth.verify_privilege(ctx.user, 'users:create:any')

    name = ctx.get_param_as_string('name')
    password = ctx.get_param_as_string('password')
    email = ctx.get_param_as_string('email', default='')
    user = users.create_user(name, password, email)
    if ctx.has_param('rank'):
        users.update_user_rank(user, ctx.get_param_as_string('rank'), ctx.user)
    if ctx.has_param('avatarStyle'):
        users.update_user_avatar(
            user,
            ctx.get_param_as_string('avatarStyle'),
            ctx.get_file('avatar', default=b''))
    ctx.session.add(user)
    ctx.session.commit()

    return _serialize(ctx, user, force_show_email=True)
Esempio n. 48
0
def get_posts_by_image(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    auth.verify_privilege(ctx.user, 'posts:reverse_search')
    content = ctx.get_file('content')

    try:
        lookalikes = posts.search_by_image(content)
    except (errors.ThirdPartyError, errors.ProcessingError):
        lookalikes = []

    return {
        'exactPost':
            _serialize_post(ctx, posts.search_by_image_exact(content)),
        'similarPosts':
            [
                {
                    'distance': lookalike.distance,
                    'post': _serialize_post(ctx, lookalike.post),
                }
                for lookalike in lookalikes
            ],
    }
Esempio n. 49
0
def update_user_token(
        ctx: rest.Context, params: Dict[str, str] = {}) -> rest.Response:
    user = users.get_user_by_name(params['user_name'])
    infix = 'self' if ctx.user.user_id == user.user_id else 'any'
    auth.verify_privilege(ctx.user, 'user_tokens:edit:%s' % infix)
    user_token = user_tokens.get_by_user_and_token(user, params['user_token'])
    versions.verify_version(user_token, ctx)
    versions.bump_version(user_token)
    if ctx.has_param('enabled'):
        auth.verify_privilege(ctx.user, 'user_tokens:edit:%s' % infix)
        user_tokens.update_user_token_enabled(
            user_token, ctx.get_param_as_bool('enabled'))
    if ctx.has_param('note'):
        auth.verify_privilege(ctx.user, 'user_tokens:edit:%s' % infix)
        note = ctx.get_param_as_string('note')
        user_tokens.update_user_token_note(user_token, note)
    if ctx.has_param('expirationTime'):
        auth.verify_privilege(ctx.user, 'user_tokens:edit:%s' % infix)
        expiration_time = ctx.get_param_as_string('expirationTime')
        user_tokens.update_user_token_expiration_time(
            user_token, expiration_time)
    user_tokens.update_user_token_edit_time(user_token)
    ctx.session.commit()
    return _serialize(ctx, user_token)
Esempio n. 50
0
def get_serialization_options(ctx: rest.Context) -> List[str]:
    return ctx.get_param_as_list('fields', default=[])
Esempio n. 51
0
def update_user(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    user = users.get_user_by_name(params['user_name'])
    versions.verify_version(user, ctx)
    versions.bump_version(user)
    infix = 'self' if ctx.user.user_id == user.user_id else 'any'
    if ctx.has_param('name'):
        auth.verify_privilege(ctx.user, 'users:edit:%s:name' % infix)
        users.update_user_name(user, ctx.get_param_as_string('name'))
    if ctx.has_param('password'):
        auth.verify_privilege(ctx.user, 'users:edit:%s:pass' % infix)
        users.update_user_password(
            user, ctx.get_param_as_string('password'))
    if ctx.has_param('email'):
        auth.verify_privilege(ctx.user, 'users:edit:%s:email' % infix)
        users.update_user_email(user, ctx.get_param_as_string('email'))
    if ctx.has_param('rank'):
        auth.verify_privilege(ctx.user, 'users:edit:%s:rank' % infix)
        users.update_user_rank(
            user, ctx.get_param_as_string('rank'), ctx.user)
    if ctx.has_param('avatarStyle'):
        auth.verify_privilege(ctx.user, 'users:edit:%s:avatar' % infix)
        users.update_user_avatar(
            user,
            ctx.get_param_as_string('avatarStyle'),
            ctx.get_file('avatar', default=b''))
    ctx.session.commit()
    return _serialize(ctx, user)
Esempio n. 52
0
def create_post(
        ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
    anonymous = ctx.get_param_as_bool('anonymous', default=False)
    if anonymous:
        auth.verify_privilege(ctx.user, 'posts:create:anonymous')
    else:
        auth.verify_privilege(ctx.user, 'posts:create:identified')
    content = ctx.get_file('content')
    tag_names = ctx.get_param_as_string_list('tags', default=[])
    safety = ctx.get_param_as_string('safety')
    source = ctx.get_param_as_string('source', default='')
    if ctx.has_param('contentUrl') and not source:
        source = ctx.get_param_as_string('contentUrl', default='')
    relations = ctx.get_param_as_int_list('relations', default=[])
    notes = ctx.get_param_as_list('notes', default=[])
    flags = ctx.get_param_as_string_list('flags', default=[])

    post, new_tags = posts.create_post(
        content, tag_names, None if anonymous else ctx.user)
    if len(new_tags):
        auth.verify_privilege(ctx.user, 'tags:create')
    posts.update_post_safety(post, safety)
    posts.update_post_source(post, source)
    posts.update_post_relations(post, relations)
    posts.update_post_notes(post, notes)
    posts.update_post_flags(post, flags)
    posts.test_sound(post, content)
    if ctx.has_file('thumbnail'):
        posts.update_post_thumbnail(post, ctx.get_file('thumbnail'))
    ctx.session.add(post)
    ctx.session.flush()
    create_snapshots_for_post(post, new_tags, None if anonymous else ctx.user)
    alternate_format_posts = posts.generate_alternate_formats(post, content)
    for alternate_post, alternate_post_new_tags in alternate_format_posts:
        create_snapshots_for_post(
            alternate_post,
            alternate_post_new_tags,
            None if anonymous else ctx.user)
    ctx.session.commit()
    return _serialize_post(ctx, post)
Esempio n. 53
0
def update_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    post = _get_post(params)
    versions.verify_version(post, ctx)
    versions.bump_version(post)
    if ctx.has_file('content'):
        auth.verify_privilege(ctx.user, 'posts:edit:content')
        posts.update_post_content(post, ctx.get_file('content'))
    if ctx.has_param('tags'):
        auth.verify_privilege(ctx.user, 'posts:edit:tags')
        new_tags = posts.update_post_tags(
            post, ctx.get_param_as_string_list('tags'))
        if len(new_tags):
            auth.verify_privilege(ctx.user, 'tags:create')
            db.session.flush()
            for tag in new_tags:
                snapshots.create(tag, ctx.user)
    if ctx.has_param('safety'):
        auth.verify_privilege(ctx.user, 'posts:edit:safety')
        posts.update_post_safety(post, ctx.get_param_as_string('safety'))
    if ctx.has_param('source'):
        auth.verify_privilege(ctx.user, 'posts:edit:source')
        posts.update_post_source(post, ctx.get_param_as_string('source'))
    elif ctx.has_param('contentUrl'):
        posts.update_post_source(post, ctx.get_param_as_string('contentUrl'))
    if ctx.has_param('relations'):
        auth.verify_privilege(ctx.user, 'posts:edit:relations')
        posts.update_post_relations(
            post, ctx.get_param_as_int_list('relations'))
    if ctx.has_param('notes'):
        auth.verify_privilege(ctx.user, 'posts:edit:notes')
        posts.update_post_notes(post, ctx.get_param_as_list('notes'))
    if ctx.has_param('flags'):
        auth.verify_privilege(ctx.user, 'posts:edit:flags')
        posts.update_post_flags(post, ctx.get_param_as_string_list('flags'))
    if ctx.has_file('thumbnail'):
        auth.verify_privilege(ctx.user, 'posts:edit:thumbnail')
        posts.update_post_thumbnail(post, ctx.get_file('thumbnail'))
    post.last_edit_time = datetime.utcnow()
    ctx.session.flush()
    snapshots.modify(post, ctx.user)
    ctx.session.commit()
    return _serialize_post(ctx, post)
Esempio n. 54
0
def process_request(ctx: rest.Context) -> None:
    ''' Bind the user to request. Update last login time if needed. '''
    bump_login = ctx.get_param_as_bool('bump-login', default=False)
    auth_user = _get_user(ctx, bump_login)
    if auth_user:
        ctx.user = auth_user