def validate_list(name): if re.match(r"[a-z0-9-_]+", name) is None: abort(400, "Invalid list name") all_lists = get_all_list_names() if name not in all_lists: abort(404, "List not found")
def got_build(project=None, branch=None, system=None): '''got build data from client''' if not is_authenticated_for_project(project): abort(401, 'Not authorized.') try: data = request.json except ValueError: data = None if data: init_dict_using_model(data, BUILDJSONMDL) if data is None or not validate_dict(data, BUILDJSONMDL) or not validate_status_codes(data): abort(400, 'Bad JSON, expected: {\n' \ '"upstream":"upstream url",\n' \ '"client":"client name (computer)",\n' \ '"commit":"commit sha",\n' \ '"force":true/false,\n' \ '"description":"commit description",\n' \ '"build":{"status":-1/0/1, "log":"base64"},\n' \ '"test":{"status":-1/0/1, "log":"base64"},\n' \ '"package":{"status":-1/0/1, "log":"base64", "zip":"base64"},\n' \ '"analyze":{"status":number of warnings, "log":"base64"},\n' \ '"github":{"user":"******", "repo":"github repository"}\n' \ '}\n' \ 'status -1 == skipped\nstatus 0 == failed\nstatus 1 == OK\n' \ 'force replaces build if already submitted for the commit\n' \ 'logs and files should be base64 encoded\n' \ 'specify github for post-hook issues\n') save_build(project, branch, system, data) return 'OK!'
def delete_fsdate(project=None, branch=None, system=None, fsdate=None): '''got branch delete request from client''' if not is_authenticated_for_project(project): abort(401, 'Not authorized.') if not delete_build(project, branch, system, fsdate): abort(400, 'System does not exist.') return 'OK!'
def delete_project(project=None): '''got project delete request from client''' if not is_authenticated_for_project(project): abort(401, 'Not authorized.') if not delete_build(project): abort(400, 'Project does not exist.') return 'OK!'
def display_team(): sort_order = request.query.get('sort') team_name = request.query.get('team') team = Team.query().filter(Team.name == team_name).get() if not team: abort(404, 'team not found') data_list = [] for map in MAPS: data_list.append(_get_team_map_win_loss(team, map)) data_list = _sort_data_list(sort_order, data_list) template_values = { 'headers': _add_sort_order_to_headers('/team/', ['Map', 'Games', 'Wins', 'Percentage'], {'team': team_name}), 'data_list': data_list, 'color': 3 } return respond(JINJA_ENV.get_template('data_view.html'), template_values)
def get_build_file(project=None, branch=None, system=None, fsdate=None, bfile=None): '''get file for build''' validate_build(project, branch, system) ext = os.path.splitext(bfile)[1] path = os.path.join(SETTINGS['builds_directory'], project) path = os.path.join(path, branch) path = os.path.join(path, system) path = os.path.join(path, fsdate) if not os.path.exists(path): abort(404, "Build does not exist.") if bfile == 'build-status.png': response.set_header('Cache-control', 'no-cache') response.set_header('Pragma', 'no-cache') if not failure_for_build(project, branch, system, fsdate): return static_file('ok.png', root='media/status/') return static_file('fail.png', root='media/status/') elif ext == '.zip': return static_file(bfile, root=path) elif ext == '.bz2': return static_file(bfile, root=path) elif ext == '.txt': response.content_type = 'text/plain' path = os.path.join(path, bfile.replace('.txt', '.bz2')) if os.path.exists(path): return bz2.BZ2File(path).read() abort(404, 'No such file.')
def parse_recipe(path): '''parse recipe data from tgz file''' def read_recipe(path): '''read recipe data from tar.gz''' try: ret = pndbuild.readgz(path) except pndbuild.PNDBUILDException as exc: upload_fail(500, exc) recipe = ret[0] pndbuild_data = ret[1] if not pndbuild_data: upload_fail(500, _('PNDBUILD data is missing')) check = check_recipe(recipe) if not check[0]: if is_json_request(): upload_fail(400, '\n'.join(check[1])) else: upload_fail(400, '<br/>'.join(check[1])) return ret try: ret = read_recipe(path) except UploadJSONFailure as exc: os.remove(path) abort(exc.httpcode, str(exc)) return ret
def search_recipes_query(): '''redirect query syntaxed search to pretty syntax search''' if is_json_request(): abort(400, _('use /search/<query> instead')) query = request.query.get('q') if not query: return template('recipes', user=None, results=[]) return redirect('/search/{}'.format(query))
def change_settings(self): self._check_cookie() conf = configparser.ConfigParser(allow_no_value=True) conf.read('settings.ini') if self.user: return dict(settings=conf, user=self.user) else: abort(401, "You have no access to this page")
def change_password(self): self._check_cookie() success = request.query.success or 0 if str(success) == '1': return template('change_password', user=self.user, success=True) else: if self.user: return dict(user=self.user, success=False) else: abort(401, 'You are not authorised')
def readpost(yy, mm, dd, slug): locator = '/%04d/%02d/%02d/%s' % (yy, mm, dd, slug, ) if locator not in POSTS: abort(404, 'Article not found!') post = POSTS[locator] return {'title': TITLE, 'post': post, 'disqus_shortname': DISQUS_SHORTNAME}
def change_language(lang=None): '''change language''' if lang not in TRANSLATIONS: abort(404, _('Unfortunately we do not have translation for {} locale').format(lang)) SESSION['lang'] = lang SESSIONMANAGER.save(SESSION) if is_json_request(): return status_json_ok() return redirect(lastpage())
def change_style(style=None): '''change style''' if style not in STYLES: abort(404) SESSION['style'] = style SESSIONMANAGER.save(SESSION) if is_json_request(): return status_json_ok() return redirect(lastpage())
def delete_messages_accepted(self): self._check_cookie() id_ = request.query.id or None if id_ == "None": id_ = None if self.user: deleted = self.db_engine.delete_messages(id_) return dict(deleted=deleted, user=self.user) else: abort(401, "You have no access to this page")
def userdel(self): self._check_cookie() result = request.query.result if self.user: return dict(user=self.user, result=result, users=self.db_engine.get_user_list()) else: abort(401, 'You are not authorised')
def user_account(user=None): '''user account page''' # pylint: disable=too-many-branches if USER['name'] != user: abort(403) def gather_errors(): '''validate edit''' errors = [] jsstr = js_translations('register') email = request.forms.get('email') password1 = request.forms.get('password') password2 = request.forms.get('password_confirm') if password1 != password2: errors.append(jsstr['password_confirm']) if not email or not re.match(r'[^@]+@[^@]+\.[^@]+', email): errors.append(jsstr['email']) if not errors: if password1: ret = USERMANAGER.get_user(user, SESSION['sessionid'], (password1, SESSION['CSRF']), email) else: ret = USERMANAGER.get_user(user, SESSION['sessionid'], email=email) if not ret: errors.append(_('Database error: Failed to create user into database')) if password1: logout() return errors if request.method == 'POST': errors = gather_errors() if not errors: if is_json_request(): return status_json_ok() return redirect('/user/{}/edit'.format(user)) else: if is_json_request(): return dump_json({'status': 'fail', 'errors': errors}) return template('useredit', errors=errors) if is_json_request(): sessions = [] key_filter = ['CSRF', 'valid'] for sid in USER.get('sessions'): data = SESSIONMANAGER.get_session(sid) if not data: continue for key in key_filter: if key in data: del data[key] sessions.append(data) return dump_json({'sessions': sessions}) return template('useredit', errors=[])
def system_page(project=None, branch=None, system=None): '''got branch delete request from client''' validate_build(project, branch, system) data = get_build_data(project, branch, system, 'current') if not data: abort(404, 'Builds for system not found') if is_json_request(): return dump_json(clean_build_json(data)) admin = True if request.environ.get('REMOTE_ADDR') == '127.0.0.1' else False return template('build', admin=admin, build=data, standalone=True)
def _safe_get_entity(entity_key, model_type=None): entity = ndb.Key(urlsafe=entity_key).get() if not entity: abort(404, 'entity not found') if model_type: if not isinstance(entity, model_type): abort(403, 'not the right type') return entity
def abandon_recipe(pkgname=None): '''abandon recipe''' recipe = RECIPEMANAGER.get_recipe(pkgname) if not recipe: abort(400, _('recipe must exist')) if not USER or USER['name'] != recipe['user']: abort(403) RECIPEMANAGER.set_maintainer(pkgname, '') if is_json_request(): return status_json_ok() return redirect('/recipe/{}'.format(pkgname))
def adopt_recipe(pkgname=None): '''adopt recipe''' recipe = RECIPEMANAGER.get_recipe(pkgname) if not recipe: abort(400, _('recipe must exist')) if recipe['maintainer']: abort(403, _('this recipe is not abadoned')) RECIPEMANAGER.set_maintainer(pkgname, USER['name']) if is_json_request(): return status_json_ok() return redirect('/recipe/{}'.format(pkgname))
def delete_build_ui(project=None, branch=None, system=None, fsdate=None): '''delete build using get interface''' admin = True if request.environ.get('REMOTE_ADDR') == '127.0.0.1' else False if not admin: abort(403, 'You are not allowed to do this') delete_build(project, branch, system, fsdate) if is_json_request(): return 'OK!' if build_exists(project, branch, system): return redirect('/build/{}/{}/{}'.format(project, branch, system)) return redirect('/')
def list_delete(): name = request.forms.get('list_name', None).lower() if name is None: abort(400, "List name not specified") all_lists = get_all_list_names() if name not in all_lists: abort(400, "List does not exists") delete_list(name) redirect("/")
def list_add(): name = request.forms.get('list_name', None).lower() if name is None: abort(400, "List name not specified") all_lists = get_all_list_names() if name in all_lists: abort(400, "List already exists") update_list(name, []) redirect("/l/" + name)
def revoke(sessionid=None): '''revoke session''' revoke_session = SESSIONMANAGER.load(sessionid) if not revoke_session: abort(400, _('revoked session must exist')) if revoke_session['name'] != USER['name']: abort(403) USER['sessions'].remove(sessionid) SESSIONMANAGER.remove(sessionid) USERMANAGER.set_user(USER['name'], USER) if is_json_request(): return status_json_ok() return redirect(lastpage())
def reject_recipe_revision(pkgname=None, revision=None): '''reject recipe revision''' recipe = RECIPEMANAGER.get_revision(pkgname, revision) if not recipe or not recipe.get('parent'): abort(400, _('recipe and revision must exist')) if not USER or USER['name'] != recipe['maintainer']: abort(403) RECIPEMANAGER.remove_revision(pkgname, recipe['revision'], remove_comments=True) if is_json_request(): return status_json_ok() if revision: return redirect('/recipe/{}'.format(pkgname)) return redirect('/user/{}/recipes'.format(USER['name']))
def do_useradd(self): username = request.forms.get('username') if self.user: try: if self.db_engine.add_user(username): redirect('/settings/useradd?result=created') else: redirect('/settings/useradd?result=error') except sqlite3.IntegrityError: redirect('/settings/useradd?result=duplicate') except sqlite3.OperationalError: redirect('/settings/useradd?result=error') else: abort(401, 'You are not authorised')
def recipe_revision_page(pkgname=None, revision=None): '''recipe revision page''' if revision: recipe = RECIPEMANAGER.get_revision(pkgname, revision) else: recipe = RECIPEMANAGER.get_recipe(pkgname) if not recipe: abort(404) comments = RECIPEMANAGER.query_comments('WHERE pkgname = ? AND revision = ?', (pkgname, recipe['revision'])) if is_json_request(): del recipe['recipedir'] recipe['comments'] = comments return dump_json(recipe) return template('recipe', recipe=recipe, comments=comments)
def display_game(): team_a = request.query.get(Game.TEAM_A) team_b = request.query.get(Game.TEAM_B) map = request.query.get(Game.MAP) game = None if team_a and team_b and map: game = _get_game(team_a, team_b, map) if game: response.headers['Content-Type'] = 'application/json' logging.info(game.to_json()) response.body = json.dumps(game.to_json()) return response else: abort(404, 'game not found')
def create_comment_for_revision(pkgname=None, revision=None): '''create comment for recipe revision''' comment = request.forms.get('comment') if not comment: abort(400, _('comment field must be provided')) if revision: recipe = RECIPEMANAGER.get_revision(pkgname, revision) else: recipe = RECIPEMANAGER.get_recipe(pkgname) if not recipe: abort(400, _('recipe and revision must exist')) RECIPEMANAGER.create_comment(pkgname, recipe['revision'], USER['name'], comment) if is_json_request(): return status_json_ok() if revision: return redirect('/recipe/{}/{}'.format(pkgname, revision)) return redirect('/recipe/{}'.format(pkgname))
def accept_recipe_revision(pkgname=None, revision=None): '''reject recipe revision''' recipe = RECIPEMANAGER.get_revision(pkgname, revision) if not recipe or not recipe.get('parent'): abort(400, _('recipe and revision must exist')) if not USER or USER['name'] != recipe['maintainer']: abort(403) RECIPEMANAGER.accept_revision(pkgname, revision) user = USERMANAGER.get_user(recipe['user']) if user and user['level'] < LEVELS['contributor']: user['level'] = LEVELS['contributor'] USERMANAGER.set_user(user['name'], user) if is_json_request(): return status_json_ok() if revision: return redirect('/recipe/{}'.format(pkgname)) return redirect('/user/{}/recipes'.format(USER['name']))
def delete_build(project, branch=None, system=None, fsdate=None): '''delete build''' # pylint: disable=too-many-branches validate_build(project, branch, system) parentpath = None buildpath = os.path.join(SETTINGS['builds_directory'], project) if branch: parentpath = buildpath buildpath = os.path.join(buildpath, branch) if system: parentpath = buildpath buildpath = os.path.join(buildpath, system) if fsdate: parentpath = buildpath currentpath = os.path.join(buildpath, 'current') if fsdate == 'current': if os.path.lexists(currentpath): fsdate = os.readlink(currentpath) else: abort(404, 'Current build does not exist') buildpath = os.path.join(buildpath, fsdate) if not os.path.isdir(buildpath): return False import shutil shutil.rmtree(buildpath) if fsdate and os.path.lexists(currentpath): current = os.readlink(currentpath) if current == fsdate: latest = os.path.basename(sorted(os.listdir(parentpath))[0]) if os.path.lexists(currentpath): os.unlink(currentpath) if latest != 'current': os.symlink(latest, currentpath) if fsdate and not os.listdir(parentpath): delete_build(project, branch, system) if system and not fsdate and not os.listdir(parentpath): delete_build(project, branch) if branch and not system and not os.listdir(parentpath): delete_build(project) return True
def check_credentials(**kwargs): # Connect to the database. conn = sqlite3.connect(config["paths"]["file_auth_database"]) c = conn.cursor() c.execute("SELECT SessionID FROM secure_login") rows = c.fetchall() c.close() for row in rows: for col in row: username = request.get_cookie("username", secret=col) if username != None: return fn(**kwargs) break else: pass abort(401)
def delete_recipe_revision(pkgname=None, revision=None): '''delete recipe revision''' if revision: recipe = RECIPEMANAGER.get_revision(pkgname, revision) else: recipe = RECIPEMANAGER.get_recipe(pkgname) if not recipe: abort(400, _('recipe and revision must exist')) if not USER or (USER['level'] < LEVELS['moderator'] and USER['name'] != recipe['user']): abort(403) if revision: RECIPEMANAGER.remove_revision(pkgname, recipe['revision'], remove_comments=True) else: RECIPEMANAGER.remove_recipe(pkgname, remove_revisions=True, remove_comments=True) if is_json_request(): return status_json_ok() if recipe.get('parent'): return redirect('/recipe/{}'.format(pkgname)) return redirect('/user/{}/recipes'.format(USER['name']))
def get_recipe_revision_file(pkgname=None, revision=None, recipefile=None): '''fetch recipe revision file''' if revision: recipe = RECIPEMANAGER.get_revision(pkgname, revision) else: recipe = RECIPEMANAGER.get_recipe(pkgname) if not recipe: abort(404) path = os.path.join('userdata/recipes', recipe['pkgname'], recipe['directory']) if recipefile == 'PNDBUILD': if request.query.get('syntax'): data = None with open(os.path.join(path, recipefile), 'r') as fle: data = fle.read() if not data: abort(404, _('PNDBUILD file not found')) syntax = replace.syntax(data, 'bash') return syntax if is_ajax_request() else template('syntax', title='PNDBUILD', syntax=syntax) return static_file(recipefile, root=path, mimetype='text/plain') return static_file(recipefile, root=path, download=True, mimetype='application/octet-stream')
def list_update(name): list_item_text = request.forms.get('list_item_text', None) if list_item_text is None: abort(400, "List item not specified") validate_list(name) new_item = { "text": list_item_text, "creation_date": datetime.datetime.now().isoformat(), "is_checked": False } list_contents = get_list(name) list_contents.append(new_item) update_list(name, list_contents) redirect("/l/" + name)
def display_team(): sort_order = request.query.get('sort') team_name = request.query.get('team') team = Team.query().filter(Team.name == team_name).get() if not team: abort(404, 'team not found') data_list = [] for map in MAPS: data_list.append(_get_team_map_win_loss(team, map)) data_list = _sort_data_list(sort_order, data_list) template_values = { 'headers': _add_sort_order_to_headers('/team/', ['Map', 'Games', 'Wins', 'Percentage'], {'team' :team_name}), 'data_list': data_list, 'color': 3 } return respond(JINJA_ENV.get_template('data_view.html'), template_values)
def useradd(self): self._check_cookie() result = request.query.result if self.user: return dict(user=self.user, result=result) else: abort(401, 'You are not authorised')