privilege.py 2.37 KB
# -*- coding: utf-8 -*-


from flask import request

from server.database import db_adapter
from server.database.models import User, UserToken
from server.utils import get_now, get_config
from server.utils.api_response import unauthorized, forbidden, insecurity_request


def token_required(func):
    """
    User must login when this decorator is enabled
    (for both user and admin)
    """
    def authenticate_and_call(*args, **kwargs):
        if not __validate_token():
            return unauthorized("login required")
        return func(*args, **kwargs)

    # keep the original func name for API intput/output validation
    # where original name is required
    authenticate_and_call.original = func.__name__
    if hasattr(func, "original"):
        authenticate_and_call.original = func.original

    return authenticate_and_call


def admin_privilege_required(func):
    """
    user must login , hackathon_name must be available,
    and 'user' has proper admin privilege on this hackathon
    """

    def authenticate_and_call(*args, **kwargs):
        user = __validate_token()
        if not user:
            return unauthorized("login required")

        if not user.role == 'admin':
            return forbidden("Permission denied need admin role")

        return func(*args, **kwargs)

    # keep the original func name for API intput/output
    # validation where original name is required
    authenticate_and_call.original = func.__name__
    if hasattr(func, "original"):
        authenticate_and_call.original = func.original

    return authenticate_and_call


def white_list_check(func):
    """
    check request's ip whether in config's white_list
    """
    def authenticate_and_call(*args, **kwargs):
        if request.ipaddress not in get_config('white_list'):
            return insecurity_request(message='%s' % request.ipaddress)
        return func(*args, **kwargs)

    authenticate_and_call.original = func.__name__
    if hasattr(func, "original"):
        authenticate_and_call.original = func.original
    return authenticate_and_call


def __validate_token():
    if 'token' not in request.headers:
        return False

    t = db_adapter.find_first_object(UserToken,
                                     UserToken.token==request.headers['token'],
                                     UserToken.expire_date<=get_now())
    if not t:
        return False

    return t.user