def test_create_api_key(client, auth, app):
    # test if user is not logged
    auth.auth_protected("/settings/api_key/generate", method='post')

    auth.login()

    # test that successful api key generated
    with app.app_context():
        api_key = get_user(login="******")['api_key']
    response = client.post("/settings/api_key/generate", follow_redirects=True)
    assert gettext('New API key generated.').encode('utf-8') in response.data
    with app.app_context():
        assert api_key != get_user(login="******")['api_key']
Exemplo n.º 2
0
 def wrapped_view(**kwargs):
     api_key = request.headers.get("X-Api-Key")
     if api_key is None:
         user = get_user(user_id=session.get('user_id'))
     else:
         user = get_user(api_key=api_key)
     if user is None or user['gitea_token'] is None:
         return {"message": gettext(u'ERROR: Gitea Token not configured')}, 503
     try:
         GiteaAPI(user['gitea_token']).repo_get_commits({'sha': 'master'}).json()
     except (JSONDecodeError, GiteaAPIError):
         return {"message": gettext(u'ERROR: Can\'t connect to Gitea server')}, 503
     return view(**kwargs)
Exemplo n.º 3
0
def register():
    if request.method == 'POST':
        login = request.form.get('login')
        password = request.form.get('password')
        confirmed_password = request.form.get('confirmed_password')
        error = None

        if not login:
            error = gettext(u'Login is required.')
        elif not password:
            error = gettext(u'Password is required.')
        elif not password == confirmed_password:
            error = gettext(u'Password not confirmed.')
        elif get_user(login=login) is not None:
            error = gettext(u'User is already registered.')

        if error is None:
            insert_user(login, password)
            flash(gettext(u'Account %(login)s created.', login=login),
                  'success')
            return redirect(url_for('admin.register'))

        if error:
            flash(error, 'fail')

    return render_template('admin/register.html', isLogged=True)
Exemplo n.º 4
0
def edit_password(login):
    user = get_user(login=login)
    if user is None:
        flash(gettext(u'User doesn\'t exist.'), 'fail')
        return redirect(url_for('admin.index'))
    else:
        if request.method == 'POST':
            password = request.form.get('password')
            confirmed_password = request.form.get('confirmed_password')
            error = None

            if not password:
                error = gettext(u'Password is required.')
            elif not password == confirmed_password:
                error = gettext(u'Password not confirmed.')

            if error is None:
                update_password(user['id'], password)
                flash(
                    gettext(u'User %(login)s password changed.',
                            login=user['login']), 'success')
                return redirect(url_for('admin.index'))

            if error:
                flash(error, 'fail')
        return render_template('admin/edit_password.html',
                               user=user,
                               isLogged=True)
Exemplo n.º 5
0
def save():
    path = request.form.get('path', '')
    data = request.form.get('data')
    user = get_user(user_id=session.get('user_id'))

    if not data:
        flash(gettext(u'No data to update.'), 'fail')
        return redirect(url_for('configuration_files.index'))
    if path:
        try:
            req = GiteaAPI(user['gitea_token']).repo_get_contents(path)
            if isinstance(req.json(), list):
                raise GiteaAPIError('Cannot save a folder, must be a file.')
            GiteaAPI(user['gitea_token']).repo_put_contents(
                path,
                data=json_dumps({
                    'content':
                    str(b64encode(data.encode('utf-8')), 'utf-8'),
                    'sha':
                    req.json()['sha']
                }))
            flash(gettext(u'File contents updated.'), 'success')
        except (requests.exceptions.RequestException, GiteaAPIError) as e:
            flash(gettext(u'Error file does not exist.'), 'fail')
            current_app.logger.error(f"{e}")
            return redirect(url_for('configuration_files.index'))
    else:
        path = ''
        flash(gettext(u'Error file path is undefined.'), 'fail')
    return redirect(url_for('configuration_files.index', path=path))
Exemplo n.º 6
0
def remove():
    path = request.args.get('path')
    user = get_user(user_id=session.get('user_id'))
    error = False

    if request.method == 'POST':
        try:
            req = GiteaAPI(user['gitea_token']).repo_get_contents(
                path, {'ref': 'master'})
            if isinstance(req.json(), list):
                raise GiteaAPIError('Cannot delete a folder, must be a file.')
            GiteaAPI(user['gitea_token']).repo_delete_contents(
                path, data=json_dumps({'sha': req.json()['sha']}))
        except (requests.exceptions.RequestException, GiteaAPIError) as e:
            flash(gettext(u'Error file does not exist.'), 'fail')
            error = True
            current_app.logger.error(f"{e}")
        else:
            flash(gettext(u'File deleted.'), 'success')
        return redirect(url_for('configuration_files.index'))
    else:
        try:
            req = GiteaAPI(user['gitea_token']).repo_get_contents(
                path, {'ref': 'master'})
            if isinstance(req.json(), list):
                raise GiteaAPIError('Cannot delete a folder, must be a file')
        except (requests.exceptions.RequestException, GiteaAPIError) as e:
            flash(gettext(u'Error file does not exist.'), 'fail')
            current_app.logger.error(f"{e}")
            return redirect(url_for('configuration_files.index'))
    return render_template('configuration_files/remove.html',
                           path=path,
                           error=error,
                           isLogged=True)
def gitea_connect():
    user = get_user(user_id=session.get('user_id'))
    gitea_token = request.form.get('gitea_token')
    error = None

    if user['gitea_token'] is not None:
        error = gettext(u'Your account is already linked with Gitea.')
    elif not gitea_token:
        error = gettext(u'Token is required.')

    if error is None:
        # test if API works
        try:
            GiteaAPI(gitea_token).user_get_current()
        except (requests.exceptions.RequestException, GiteaAPIError) as e:
            error = gettext(u'Error account not linked.')
            current_app.logger.error(f"{e}")
        else:
            update_token(session.get('user_id'), gitea_token)
            flash(gettext(u'Your account is now linked with Gitea.'), 'success')

    if error:
        flash(error, 'fail')

    return redirect(url_for('settings.index'))
Exemplo n.º 8
0
def load_logged_in_user():
    user_id = session.get('user_id')

    if user_id is None:
        g.user = None
    else:
        g.user = get_user(user_id=user_id)
Exemplo n.º 9
0
def confirm_save():
    path = request.form.get('path')
    new_data = request.form.get('data')
    old_data = None
    diffs = None
    user = get_user(user_id=session.get('user_id'))

    try:
        req = GiteaAPI(user['gitea_token']).repo_get_contents(
            path, {'ref': 'master'})
        if isinstance(req.json(), list):
            raise GiteaAPIError('Cannot save a folder, must be a file.')
    except (requests.exceptions.RequestException, GiteaAPIError) as e:
        flash(gettext(u'Error file does not exist.'), 'fail')
        current_app.logger.error(f"{e}")
        return redirect(url_for('configuration_files.index'))
    else:
        old_data = b64decode(req.json()['content']).decode('utf-8')
        diffs = list(
            unified_diff(old_data.splitlines(keepends=True),
                         new_data.splitlines(keepends=True)))
        if not diffs:
            flash(gettext(u'No data to update.'), 'fail')
            return redirect(url_for('configuration_files.index', path=path))
    return render_template('configuration_files/confirm_save.html',
                           path=path,
                           new_data=new_data,
                           old_data=old_data,
                           diffs=diffs,
                           isLogged=True)
Exemplo n.º 10
0
def delete_api_key():
    user = get_user(user_id=session.get('user_id'))
    if user['api_key'] is None:
        flash(gettext(u'No API key to delete.'), 'fail')
    else:
        update_api_key(session.get('user_id'), None)
        flash(gettext(u'API key deleted.'), 'success')
    return redirect(url_for('settings.index'))
Exemplo n.º 11
0
 def wrapped_view(**kwargs):
     user = get_user(user_id=session.get('user_id'))
     if user['gitea_token'] is None:
         flash(gettext(u'Your account is not linked with a gitea account.'), 'fail')
         return redirect(url_for('settings.index'))
     try:
         GiteaAPI(user['gitea_token']).repo_get_commits({'sha': 'master'}).json()
     except (JSONDecodeError, GiteaAPIError):
         flash(gettext(u'Error can\'t get configuration files from Gitea.'), 'fail')
         return redirect(url_for('settings.index'))
     return view(**kwargs)
Exemplo n.º 12
0
def remove(login):
    user = get_user(login=login)
    if user is None:
        flash(gettext(u'User doesn\'t exist.'), 'fail')
        return redirect(url_for('admin.index'))
    else:
        if request.method == 'POST':
            delete_user(user['id'])
            flash(gettext(u'User %(login)s deleted.', login=user['login']),
                  'success')
            return redirect(url_for('admin.index'))
        return render_template('admin/remove.html', user=user, isLogged=True)
Exemplo n.º 13
0
def index():
    user = get_user(user_id=session.get('user_id'))
    gitea_user = None
    error = False
    if user['gitea_token']:
        try:
            gitea_user = GiteaAPI(user['gitea_token']).user_get_current().json()
        except (requests.exceptions.RequestException, GiteaAPIError, JSONDecodeError) as e:
            error = True
            flash(gettext(u'Error something went wrong.'), 'fail')
            current_app.logger.error(f"{e}")
    return render_template('settings/index.html', gitea_user=gitea_user, gitea=get_gitea(), api_key=user['api_key'], error=error, isLogged=True)
Exemplo n.º 14
0
def gitea_disconnect():
    user = get_user(user_id=session.get('user_id'))
    error = None

    if user['gitea_token'] is None:
        error = gettext(u'Your account is not linked with Gitea.')

    if error is None:
        update_token(user['id'], None)
        flash(gettext(u'Your account is no longer linked with Gitea.'), 'success')

    if error:
        flash(error, 'fail')

    return redirect(url_for('settings.index'))
def test_delete_api_key(client, auth, app):
    # test if user is not logged
    auth.auth_protected("/settings/api_key/delete", method='post')

    auth.login()

    # test that successful api key deleted
    response = client.post("/settings/api_key/delete", follow_redirects=True)
    assert gettext('API key deleted.').encode('utf-8') in response.data
    with app.app_context():
        assert get_user(login="******")['api_key'] is None

    # test that you can't delete API key when you haven't one
    response = client.post("/settings/api_key/delete", follow_redirects=True)
    assert gettext('No API key to delete.').encode('utf-8') in response.data
Exemplo n.º 16
0
def index():
    if request.method == 'POST':
        hostname = request.form.get('hostname')
        module = request.form.get('module')
        action = request.form.get('action')
        path = request.form.get('path')
        error = None

        if not hostname:
            error = gettext(u'Hostname is required.')
        elif not module:
            error = gettext(u'Module is required.')
        elif action not in ['save', 'restore']:
            error = gettext(u'Action is required.')
        elif not path:
            error = gettext(u'Path is required.')

        if error:
            flash(error, 'fail')
            return redirect(url_for('tasks.index'))

        if path[0] == '/':
            path = path[1:]

        user = get_user(user_id=session.get('user_id'))
        gitea = get_gitea()

        id = create_task(hostname, module, action, path,
                         datetime.now(timezone.utc))

        rabbit = RabbitMQ()
        rabbit.create_task(
            {
                'id': id,
                'gitea': {
                    'token': user['gitea_token'],
                    'url': gitea['url'],
                    'owner': gitea['owner'],
                    'repository': gitea['repository'],
                },
                'hostname': hostname,
                'module': module,
                'action': action,
                'path': path,
            }, id)
        return redirect(url_for('tasks.task', id=id))
    else:
        return render_template('tasks/index.html', isLogged=True)
def test_gitea_disconnect(client, auth, app):
    # test if user is not logged
    auth.auth_protected("/settings/gitea/disconnect", method='post')

    auth.login()

    # test that successful gitea account unlinked
    response = client.post("/settings/gitea/disconnect", follow_redirects=True)
    assert gettext('Your account is no longer linked with Gitea.').encode(
        'utf-8') in response.data
    with app.app_context():
        assert get_user(login="******")['gitea_token'] is None

    # test that you can't unlink gitea account when it isn't linked
    response = client.post("/settings/gitea/disconnect", follow_redirects=True)
    assert gettext('Your account is not linked with Gitea.').encode(
        'utf-8') in response.data
Exemplo n.º 18
0
def index():
    ref = request.args.get('ref', 'master')
    path = request.args.get('path', '')
    user = get_user(user_id=session.get('user_id'))
    gitea = get_gitea()
    repo_contents = None
    commits = None
    error = False
    folder = False

    try:
        commits = GiteaAPI(user['gitea_token']).repo_get_commits().json()
        if not path:
            req = GiteaAPI(user['gitea_token']).repo_get_contents_list(
                {'ref': ref})
        else:
            req = GiteaAPI(user['gitea_token']).repo_get_contents(
                path, {'ref': ref})
    except (requests.exceptions.RequestException, GiteaAPIError) as e:
        flash(gettext(u'Error cannot get configuration files from Gitea.'),
              'fail')
        error = True
        current_app.logger.error(f"{e}")
        return redirect(url_for(
            'docs.index')) if ref == 'master' and path == '' else redirect(
                url_for('configuration_files.index'))
    else:
        repo_contents = req.json()
        folder = isinstance(repo_contents, list)
        if not folder:
            try:
                repo_contents['content'] = b64decode(
                    repo_contents['content']).decode('utf-8')
            except UnicodeDecodeError:
                flash(gettext(u'Cannot read this type of file.'), 'fail')
                return redirect(url_for('configuration_files.index'))

    return render_template('configuration_files/index.html',
                           folder=folder,
                           gitea=gitea,
                           repo_contents=repo_contents,
                           commits=commits,
                           ref=ref,
                           error=error,
                           isLogged=True)
Exemplo n.º 19
0
def login():
    if request.method == 'POST':
        login = request.form.get('login')
        password = request.form.get('password')
        error = None

        if not login:
            error = gettext(u'Login is required.')
        elif not password:
            error = gettext(u'Password is required.')
        elif not check_password(login, password):
            error = gettext(u'Incorrect login/password.')

        if error is None:
            session.clear()
            user = get_user(login)
            session["user_id"] = user["id"]
            flash(gettext(u'Welcome %(login)s.', login=user['login']), 'success')
            return redirect(url_for('tasks.index'))

        if error:
            flash(error, 'fail')

    return render_template('auth/login.html', isLogged=False)
def test_gitea_connect(client, auth, app):
    # test if user is not logged
    auth.auth_protected(
        "/settings/gitea/connect",
        data={"gitea_token": config["USER"]["GITEA_TEST_TOKEN"]},
        method='post')

    auth.login()

    # test that you can't link your account if he is already linked
    response = client.post("/settings/gitea/connect",
                           data={"gitea_token": "aaaaaa"},
                           follow_redirects=True)
    assert gettext('Your account is already linked with Gitea.').encode(
        'utf-8') in response.data

    # unlink account from gitea
    client.post("/settings/gitea/disconnect", follow_redirects=True)

    # test that account was not linked with fake token
    response = client.post("/settings/gitea/connect",
                           data={"gitea_token": "aaaaaa"},
                           follow_redirects=True)
    assert gettext('Error account not linked.').encode(
        'utf-8') in response.data

    # test that successful account linked
    response = client.post(
        "/settings/gitea/connect",
        data={"gitea_token": config["USER"]["GITEA_TEST_TOKEN"]},
        follow_redirects=True)
    assert gettext('Your account is now linked with Gitea.').encode(
        'utf-8') in response.data
    with app.app_context():
        assert get_user(
            login="******")['gitea_token'] == config["USER"]["GITEA_TEST_TOKEN"]
Exemplo n.º 21
0
    def post(self):
        """
        Create one task
        ---
        tags:
          - Tasks
        parameters:
          - name: task
            in: body
            description: The task to create
            required: true
            schema:
                required:
                  - hostname
                  - module
                  - action
                  - path
                properties:
                  hostname:
                    type: string
                    example: 192.168.0.1
                  module:
                    type: string
                    example: pfsense
                  action:
                    type: string
                    enum: [save, restore]
                    example: save
                  path:
                    type: string
                    example: /pfsense/backup12.zip
        responses:
          201:
            description: Task created
            examples:
                task_1: { 'id': 1 }
                task_2: { 'id': 2 }
          400:
            description: Task not created
        """
        args = tasks_parser.parse_args()
        if not args.hostname or not args.module or args.action not in ['save', 'restore'] or not args.path:
            return {"message": gettext(u'ERROR: Bad Request')}, 400
        else:
            api_key = request.headers.get("X-Api-Key")
            if api_key is None:
                user = get_user(user_id=session.get('user_id'))
            else:
                user = get_user(api_key=api_key)

            if args.path[0] == '/':
                args.path = args.path[1:]

            gitea = get_gitea()

            id = create_task(args.hostname, args.module, args.action, args.path, datetime.now(timezone.utc))

            rabbit = RabbitMQ()
            rabbit.create_task({
                'id': id,
                'gitea': {
                    'token': user['gitea_token'],
                    'url': gitea['url'],
                    'owner': gitea['owner'],
                    'repository': gitea['repository'],
                },
                'hostname': args.hostname,
                'module': args.module,
                'action': args.action,
                'path': args.path,
            }, id)

            return {'id': id}, 201
Exemplo n.º 22
0
 def wrapped_view(**kwargs):
     api_key = request.headers.get("X-Api-Key")
     user = get_user(api_key=api_key)
     if g.user is None and (user is None or user['api_key'] is None):
         return {"message": gettext(u'ERROR: Unauthorized')}, 401
     return view(**kwargs)