<commit_before>from __future__ import unicode_literals, division, absolute_import
from builtins import *  # pylint: disable=unused-import, redefined-builtin

import base64

from flask import request, jsonify, session as flask_session
from flask_login import login_user, LoginManager, current_user, current_app
from flask_restplus import inputs
from werkzeug.security import check_password_hash

from flexget.api import api, APIResource, app, Unauthorized
from flexget.utils.database import with_session
from flexget.webserver import User

login_manager = LoginManager()
login_manager.init_app(app)


@login_manager.request_loader
@with_session
def load_user_from_request(request, session=None):
    auth_value = request.headers.get('Authorization')

    if not auth_value:
        return

    # Login using api key
    if auth_value.startswith('Token'):
        try:
            token = auth_value.replace('Token ', '', 1)
            return session.query(User).filter(User.token == token).first()
        except (TypeError, ValueError):
            pass

    # Login using basic auth
    if auth_value.startswith('Basic'):
        try:
            credentials = base64.b64decode(auth_value.replace('Basic ', '', 1))
            username, password = credentials.split(':')
            user = session.query(User).filter(User.name == username).first()
            if user and user.password and check_password_hash(user.password, password):
                return user
            else:
                return None
        except (TypeError, ValueError):
            pass


@login_manager.user_loader
@with_session
def load_user(username, session=None):
    return session.query(User).filter(User.name == username).first()


@app.before_request
def check_valid_login():
    # Allow access to root, login and swagger documentation without authentication
    if request.path == '/' or request.path.startswith('/auth/login') or \
            request.path.startswith('/auth/logout') or request.path.startswith('/swagger'):
        return

    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()


# API Authentication and Authorization
auth_api = api.namespace('auth', description='Authentication')

login_api_schema = api.schema('auth.login', {
    'type': 'object',
    'properties': {
        'username': {'type': 'string'},
        'password': {'type': 'string'}
    }
})

login_parser = api.parser()
login_parser.add_argument('remember', type=inputs.boolean, required=False, default=False,
                          help='Remember login (sets persistent session cookies)'
                          )


@auth_api.route('/login/')
class LoginAPI(APIResource):
    @api.expect((login_api_schema, 'Username and Password'))
    @api.response(Unauthorized)
    @api.response(200, 'Login successful')
    @api.doc(parser=login_parser)
    def post(self, session=None):
        """ Login with username and password """
        data = request.json
        user_name = data.get('username')
        password = data.get('password')

        if data:
            user = session.query(User).filter(User.name == user_name.lower()).first()
            if user:
                if user_name == 'flexget' and not user.password:
                    raise Unauthorized(
                        message='If this is your first time running the WebUI you need to set a password via'
                                ' the command line by running `flexget web passwd <new_password>`')

                if user.password and check_password_hash(user.password, password):
                    args = login_parser.parse_args()
                    login_user(user, remember=args['remember'])
                    return {}

        raise Unauthorized(message='Invalid username or password')


@auth_api.route('/logout/')
class LogoutAPI(APIResource):
    @api.response(200, 'Logout successful')
    def get(self, session=None):
        """ Logout and clear session cookies """
        flask_session.clear()
        resp = jsonify({})
        resp.set_cookie('flexgetToken', '', expires=0)
        return resp<commit_msg>Tightened auth post schema<commit_after>from __future__ import unicode_literals, division, absolute_import
from builtins import *  # pylint: disable=unused-import, redefined-builtin

import base64

from flask import request, jsonify, session as flask_session
from flask_login import login_user, LoginManager, current_user, current_app
from flask_restplus import inputs
from werkzeug.security import check_password_hash

from flexget.api import api, APIResource, app, Unauthorized, empty_response
from flexget.utils.database import with_session
from flexget.webserver import User

login_manager = LoginManager()
login_manager.init_app(app)


@login_manager.request_loader
@with_session
def load_user_from_request(request, session=None):
    auth_value = request.headers.get('Authorization')

    if not auth_value:
        return

    # Login using api key
    if auth_value.startswith('Token'):
        try:
            token = auth_value.replace('Token ', '', 1)
            return session.query(User).filter(User.token == token).first()
        except (TypeError, ValueError):
            pass

    # Login using basic auth
    if auth_value.startswith('Basic'):
        try:
            credentials = base64.b64decode(auth_value.replace('Basic ', '', 1))
            username, password = credentials.split(':')
            user = session.query(User).filter(User.name == username).first()
            if user and user.password and check_password_hash(user.password, password):
                return user
            else:
                return None
        except (TypeError, ValueError):
            pass


@login_manager.user_loader
@with_session
def load_user(username, session=None):
    return session.query(User).filter(User.name == username).first()


@app.before_request
def check_valid_login():
    # Allow access to root, login and swagger documentation without authentication
    if request.path == '/' or request.path.startswith('/auth/login') or \
            request.path.startswith('/auth/logout') or request.path.startswith('/swagger'):
        return

    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()


# API Authentication and Authorization
auth_api = api.namespace('auth', description='Authentication')

login_api_schema = api.schema('auth.login', {
    'type': 'object',
    'properties': {
        'username': {'type': 'string'},
        'password': {'type': 'string'}
    },
    'required': ['username', 'password'],
    'additionalProperties': False
})

login_parser = api.parser()
login_parser.add_argument('remember', type=inputs.boolean, required=False, default=False,
                          help='Remember login (sets persistent session cookies)'
                          )


@auth_api.route('/login/')
class LoginAPI(APIResource):
    @api.validate(login_api_schema, description='Username and Password')
    @api.response(Unauthorized)
    @api.response(200, 'Login successful', model=empty_response)
    @api.doc(parser=login_parser)
    def post(self, session=None):
        """ Login with username and password """
        data = request.json
        user_name = data.get('username')
        password = <PASSWORD>('password')

        if data:
            user = session.query(User).filter(User.name == user_name.lower()).first()
            if user:
                if user_name == 'flexget' and not user.password:
                    raise Unauthorized(
                        message='If this is your first time running the WebUI you need to set a password via'
                                ' the command line by running `flexget web passwd <new_password>`')

                if user.password and check_password_hash(user.password, password):
                    args = login_parser.parse_args()
                    login_user(user, remember=args['remember'])
                    return {}

        raise Unauthorized(message='Invalid username or password')


@auth_api.route('/logout/')
class LogoutAPI(APIResource):
    @api.response(200, 'Logout successful', model=empty_response)
    def get(self, session=None):
        """ Logout and clear session cookies """
        flask_session.clear()
        resp = jsonify({})
        resp.set_cookie('flexgetToken', '', expires=0)
        return resp
{'fraction_non_alphanumeric': 0.10712589073634204, 'fraction_numerical': 0.0035629453681710215, 'mean_word_length': 2.9040333796940194, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4599678', 'n_tokens_mistral': 2301, 'n_tokens_neox': 2223, 'n_words': 574}