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']
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)
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)
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)
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))
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'))
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)
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)
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'))
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)
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)
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)
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
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
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)
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"]
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
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)