def delete(self, project_id, user_id): ''' Remove collaborator from project ''' collaborator = g.db.execute_one( """ SELECT role FROM collaborator WHERE user_id = %s AND project_id = %s LIMIT 1 """, [str(user_id), project_id]) # Give some warning if the specified user has been already removed # from the collaborators or has been never added there before if not collaborator: return OK('Specified user is not in collaborators list.') if collaborator[0] == 'Owner': abort(400, "It's not allowed to delete the owner of the project.") g.db.execute( """ DELETE FROM collaborator WHERE user_id = %s AND project_id = %s """, [str(user_id), project_id]) g.db.commit() opa_push_collaborator_data(g.db) return OK('Successfully removed user.')
def post(self, project_id): b = request.get_json() username = b['username'] user = g.db.execute_one_dict( """ SELECT * FROM "user" WHERE username = %s """, [username]) if not user: abort(400, "User not found.") num_collaborators = g.db.execute_one( """ SELECT COUNT(*) FROM collaborator WHERE user_id = %s AND project_id = %s """, [user['id'], project_id])[0] if num_collaborators != 0: return OK('Specified user is already a collaborator.') g.db.execute( """ INSERT INTO collaborator (project_id, user_id) VALUES(%s, %s) ON CONFLICT DO NOTHING """, [project_id, user['id']]) g.db.commit() return OK('Successfully added user.')
def delete(self, project_id, user_id): owner_id = g.token['user']['id'] if user_id == owner_id: abort( 400, "It's not allowed to delete the owner of the project from collaborators." ) num_collaborators = g.db.execute_one( """ SELECT COUNT(*) FROM collaborator WHERE user_id = %s AND project_id = %s """, [user_id, project_id])[0] # Give some warning if the specified user has been already removed # from the collaborators or has been never added there before if num_collaborators == 0: return OK('Specified user is not in collaborators list.') g.db.execute( """ DELETE FROM collaborator WHERE user_id = %s AND project_id = %s """, [user_id, project_id]) g.db.commit() return OK('Successfully removed user.')
def post(self, project_id): ''' Add a collaborator ''' b = request.get_json() username = b['username'] userrole = b['role'] if 'role' in b else 'Developer' # Prevent for now a project owner change # (Because with GitHub Integration the project owner's GitHub Token will be used) if userrole == 'Owner': abort(403, "A project is limited to one owner.") user = g.db.execute_one_dict( """ SELECT * FROM "user" WHERE username = %s """, [username]) if not user: abort(400, "User not found.") roles = g.db.execute_many(""" SELECT unnest(enum_range(NULL::user_role)) """) if [userrole] not in roles: abort(400, "Role unknown.") num_collaborators = g.db.execute_one( """ SELECT COUNT(*) FROM collaborator WHERE user_id = %s AND project_id = %s """, [user['id'], project_id])[0] if num_collaborators != 0: return OK('Specified user is already a collaborator.') g.db.execute( """ INSERT INTO collaborator (project_id, user_id, role) VALUES(%s, %s, %s) ON CONFLICT DO NOTHING """, [project_id, user['id'], userrole]) g.db.commit() opa_push_collaborator_data(g.db) return OK('Successfully added user.')
def get(self, project_id, job_id): ''' Clear job's cache ''' job = g.db.execute_one_dict( ''' SELECT j.name, branch from job j INNER JOIN build b ON b.id = j.build_id AND j.project_id = b.project_id LEFT OUTER JOIN "commit" c ON b.commit_id = c.id AND c.project_id = b.project_id WHERE j.id = %s AND j.project_id = %s ''', [job_id, project_id]) if not job: abort(404) key = 'project_%s_job_%s.tar.snappy' % (project_id, job['name']) storage.delete_cache(key) return OK('Cleared cache')
def post(self, project_id): b = request.get_json() if not Secrets.name_pattern.match(b['name']): abort(400, 'Secret name must be not empty alphanumeric string.') result = g.db.execute_one_dict( """ SELECT COUNT(*) as cnt FROM secret WHERE project_id = %s """, [project_id]) if result['cnt'] > 50: abort(400, 'Too many secrets.') r = g.db.execute_one( """ SELECT count(*) FROM secret WHERE project_id = %s AND name = %s """, [project_id, b['name']]) if r[0] > 0: abort(400, 'Secret with this name already exist.') value = encrypt_secret(b['value']) g.db.execute( ''' INSERT INTO secret (project_id, name, value) VALUES(%s, %s, %s) ''', [project_id, b['name'], value]) g.db.commit() return OK('Successfully added secret.')
def get(self, project_id, job_id): g.db.execute(''' INSERT INTO abort(job_id) VALUES(%s) ''', [job_id]) g.db.commit() return OK('Successfully aborted job')
def get(self, project_id, job_id): job = g.db.execute_one_dict( ''' SELECT state, type FROM job WHERE id = %s AND project_id = %s ''', [job_id, project_id]) if not job: abort(404) job_type = job['type'] job_state = job['state'] if job_type not in ('run_project_container', 'run_docker_compose'): abort(400, 'Job type cannot be restarted') if job_state not in ('error', 'failure', 'finished', 'killed'): abort(400, 'Job in state %s cannot be restarted' % job_state) g.db.execute( ''' UPDATE job SET state = 'queued', console = null, message = null WHERE id = %s ''', [job_id]) g.db.commit() return OK('Successfully restarted job')
def post(self): b = request.get_json() email = b['email'] password = b['password'] user = g.db.execute_one_dict( ''' SELECT id, password FROM "user" WHERE email = %s ''', [email]) if not user: abort(400, 'Invalid email/password combination') if not bcrypt.checkpw(password.encode('utf8'), user['password'].encode('utf8')): abort(400, 'Invalid email/password combination') token = encode_user_token(user['id']) res = OK('Logged in') res.set_cookie('token', token) return res
def delete(self, project_id, secret_id): ''' Delete a secret ''' if not validate_uuid(secret_id): abort(400, "Invalid secret uuid.") num_secrets = g.db.execute_one( """ SELECT COUNT(*) FROM secret WHERE project_id = %s and id = %s """, [project_id, secret_id])[0] if num_secrets == 0: return abort(400, 'Such secret does not exist.') num_keys = g.db.execute_one( """ SELECT COUNT(*) FROM sshkey WHERE project_id = %s and secret_id = %s """, [project_id, secret_id])[0] if num_keys != 0: return abort(400, 'Secret is still used SSH Key.') g.db.execute( """ DELETE FROM secret WHERE project_id = %s and id = %s """, [project_id, secret_id]) g.db.commit() return OK('Successfully deleted secret.')
def post(self): if os.environ['INFRABOX_ACCOUNT_SIGNUP_ENABLED'] != 'true': abort(404) b = request.get_json() email = b['email'] password1 = b['password1'] password2 = b['password2'] username = b['username'] if password1 != password2: abort(400, 'Passwords don\'t match') e = parseaddr(email) if not e: abort(400, 'Invalid email') if not e[1]: abort(400, 'Invalid email') if not username.isalnum(): abort(400, 'Username is not alphanumeric') user = g.db.execute_one_dict( ''' SELECT id, password FROM "user" WHERE email = %s ''', [email]) if user: abort(400, 'An account with this email already exists') user = g.db.execute_one_dict( ''' SELECT id, password FROM "user" WHERE username = %s ''', [username]) if user: abort(400, 'An account with this username already exists') hashed_password = bcrypt.hashpw(password1.encode('utf8'), bcrypt.gensalt()) user = g.db.execute_one_dict( ''' INSERT into "user" (username, email, password) VALUES (%s, %s, %s) RETURNING ID ''', [username, email, hashed_password]) token = encode_user_token(user['id']) g.db.commit() res = OK('Logged in') res.set_cookie('token', token) return res
def delete(self, project_id, vault_id): g.db.execute( ''' DELETE FROM vault WHERE project_id = %s and id = %s ''', [project_id, vault_id]) g.db.commit() return OK('Successfully deleted vault.')
def post(self, project_id): ''' Create new token ''' project_name = g.db.execute_one( """ SELECT name FROM project WHERE id = %s """, [project_id]) if not project_name: return abort(400, 'Invalid project id.') b = request.get_json() result = g.db.execute_one( """ SELECT COUNT(*) FROM auth_token WHERE project_id = %s AND description = %s """, [project_id, b['description']])[0] if result != 0: return abort(400, 'Token with such a description already exists.') result = g.db.execute_one_dict( """ INSERT INTO auth_token (description, scope_push, scope_pull, project_id) VALUES (%s, %s, %s, %s) RETURNING id """, [b['description'], b['scope_push'], b['scope_pull'], project_id]) token_id = result['id'] token = encode_project_token(token_id, project_id, project_name) g.db.commit() return OK('Successfully added token.', {'token': token})
def post(self): b = request.get_json() email = b['email'].lower() password = b['password'] user = g.db.execute_one_dict(''' SELECT id, password FROM "user" WHERE email = %s ''', [email]) if user and user['id'] == '00000000-0000-0000-0000-000000000000': # Admin login if not bcrypt.checkpw(password.encode('utf8'), user['password'].encode('utf8')): abort(400, 'Invalid email/password combination') else: ldap_user = authenticate(email, password) if not user: user = g.db.execute_one_dict(''' INSERT INTO "user" (email, username, name) VALUES (%s, %s, %s) RETURNING id ''', [email, ldap_user['cn'], ldap_user['displayName']]) token = encode_user_token(user['id']) g.db.commit() res = OK('Logged in') res.set_cookie('token', token) return res
def post(self): b = request.get_json() email = b['email'] password = b['password'] ldap_user = authenticate(email, password) user = g.db.execute_one_dict( ''' SELECT id FROM "user" WHERE email = %s ''', [email]) if not user: user = g.db.execute_one_dict( ''' INSERT INTO "user" (email, username, name) VALUES (%s, %s, %s) RETURNING id ''', [email, ldap_user['cn'], ldap_user['displayName']]) token = encode_user_token(user['id']) g.db.commit() res = OK('Logged in') res.set_cookie('token', token) return res
def post(self, project_id): ''' Create new cronjob ''' b = request.get_json() if not CronJobs.name_pattern.match(b['name']): abort(400, 'CronJob name must be not empty alphanumeric string.') if not croniter.is_valid('%s %s %s %s %s' % (b['minute'], b['hour'], b['day_month'], b['month'], b['day_week'])): abort(400, 'Invalid input expression') result = g.db.execute_one_dict(""" SELECT COUNT(*) as cnt FROM cronjob WHERE project_id = %s """, [project_id]) if result['cnt'] > 50: abort(400, 'Too many cronjobs.') r = g.db.execute_one(""" SELECT count(*) FROM cronjob WHERE project_id = %s AND name = %s """, [project_id, b['name']]) if r[0] > 0: abort(400, 'CronJob with this name already exist') g.db.execute(''' INSERT INTO cronjob (project_id, name, minute, hour, day_month, month, day_week, sha, infrabox_file) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s) ''', [project_id, b['name'], b['minute'], b['hour'], b['day_month'], b['month'], b['day_week'], b['sha'], b['infrabox_file']]) g.db.commit() return OK('Successfully added CronJob.')
def delete(self, project_id): if not validate_uuid4(project_id): abort(400, "Invalid project uuid.") project = g.db.execute_one_dict( """ DELETE FROM project WHERE id = %s RETURNING type """, [project_id]) if not project: abort(400, 'Project with such an id does not exist.') if project['type'] == 'github': repo = g.db.execute_one_dict( ''' SELECT name, github_owner, github_hook_id FROM repository WHERE project_id = %s ''', [project_id]) gh_owner = repo['github_owner'] gh_hook_id = repo['github_hook_id'] gh_repo_name = repo['name'] user = g.db.execute_one_dict( ''' SELECT github_api_token FROM "user" WHERE id = %s ''', [g.token['user']['id']]) gh_api_token = user['github_api_token'] headers = { "Authorization": "token " + gh_api_token, "User-Agent": "InfraBox" } url = '%s/repos/%s/%s/hooks/%s' % ( os.environ['INFRABOX_GITHUB_API_URL'], gh_owner, gh_repo_name, gh_hook_id) # TODO(ib-steffen): allow custom ca bundles requests.delete(url, headers=headers, verify=False) # TODO: delete all tables g.db.execute( ''' DELETE FROM repository WHERE project_id = %s ''', [project_id]) g.db.execute( ''' DELETE FROM collaborator WHERE project_id = %s ''', [project_id]) g.db.commit() return OK('deleted project')
def delete(self, project_id, token_id): g.db.execute(''' DELETE FROM auth_token WHERE project_id = %s and id = %s ''', [project_id, token_id]) g.db.commit() return OK('Successfully deleted token')
def post(self, project_id): project = g.db.execute_one_dict( ''' SELECT type FROM project WHERE id = %s ''', [project_id]) if not project: abort(404, 'Project not found') if project['type'] != 'upload': abort(400, 'Project is not of type "upload"') build_id = str(uuid.uuid4()) key = '%s.zip' % build_id storage.upload_project(request.files['project.zip'].stream, key) build_number = g.db.execute_one_dict( ''' SELECT count(distinct build_number) + 1 AS build_number FROM build AS b WHERE b.project_id = %s ''', [project_id])['build_number'] source_upload_id = g.db.execute_one( ''' INSERT INTO source_upload(filename, project_id, filesize) VALUES (%s, %s, 0) RETURNING ID ''', [key, project_id])[0] g.db.execute( ''' INSERT INTO build (commit_id, build_number, project_id, source_upload_id, id) VALUES (null, %s, %s, %s, %s) ''', [build_number, project_id, source_upload_id, build_id]) g.db.execute( ''' INSERT INTO job (id, state, build_id, type, name, project_id, dockerfile, build_only, cpu, memory) VALUES (gen_random_uuid(), 'queued', %s, 'create_job_matrix', 'Create Jobs', %s, '', false, 1, 1024); ''', [build_id, project_id]) project_name = g.db.execute_one( ''' SELECT name FROM project WHERE id = %s ''', [project_id])[0] url = '%s/dashboard/#/project/%s/build/%s/1' % ( os.environ['INFRABOX_ROOT_URL'], project_name, build_number) data = {'build': {'id': build_id, 'number': build_number}, 'url': url} g.db.commit() return OK('successfully started build', data=data)
def get(self, project_id, job_id): ''' Abort job ''' g.db.execute(''' INSERT INTO abort(job_id, user_id) VALUES(%s, %s) ''', [job_id, g.token['user']['id']]) g.db.commit() return OK('Successfully aborted job')
def post(self): body = request.get_json() g.db.execute( ''' UPDATE cluster SET enabled=%s WHERE name=%s ''', [body['enabled'], body['name']]) g.db.commit() return OK("OK")
def post(self, project_id): b = request.get_json() g.db.execute( ''' INSERT INTO vault (project_id, name, url, namespace, version, token, ca) VALUES(%s, %s, %s, %s, %s, %s, %s) ''', [ project_id, b['name'], b['url'], b['namespace'], b['version'], b['token'], b['ca'] ]) g.db.commit() return OK('Successfully added vault.')
def post(self, project_id): ''' Add new sshkey ''' b = request.get_json() if not SSHKeys.name_pattern.match(b['name']): abort(400, 'CronJob name must be not empty alphanumeric string.') result = g.db.execute_one_dict( """ SELECT id FROM secret WHERE project_id = %s AND name = %s """, [project_id, b['secret']]) if not result: abort(400, 'Secret does not exist') secret_id = result['id'] result = g.db.execute_one_dict( """ SELECT COUNT(*) as cnt FROM sshkey WHERE project_id = %s """, [project_id]) if result['cnt'] > 0: abort(400, 'Too many sshkeys') r = g.db.execute_one( """ SELECT count(*) FROM sshkey WHERE project_id = %s AND name = %s """, [project_id, b['name']]) if r[0] > 0: abort(400, 'SSH Key with this name already exist') g.db.execute( ''' INSERT INTO sshkey (project_id, name, secret_id) VALUES(%s, %s, %s) ''', [project_id, b['name'], secret_id]) g.db.commit() return OK('Successfully added SSH Key')
def post(self, project_id): b = request.get_json() result = g.db.execute_one_dict(''' INSERT INTO auth_token (description, scope_push, scope_pull, project_id) VALUES (%s, %s, %s, %s) RETURNING id ''', [b['description'], b['scope_push'], b['scope_pull'], project_id]) token_id = result['id'] token = encode_project_token(token_id, project_id) g.db.commit() return OK('Successfully added token', {'token': token})
def post(self, project_id): b = request.get_json() if not b['token']: if not b['role_id'] or not b['secret_id']: abort(400, "Invalid Vault format") g.db.execute( ''' INSERT INTO vault (project_id, name, url, namespace, version, token, ca, role_id, secret_id) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s) ''', [ project_id, b['name'], b['url'], b['namespace'], b['version'], b['token'], b['ca'], b['role_id'], b['secret_id'] ]) g.db.commit() return OK('Successfully added vault.')
def post(self): if g.token['user']['role'] != 'admin': abort(403, "updating user role is only allowed for admin user") body = request.get_json() if body['id'] == '00000000-0000-0000-0000-000000000000': abort(403, "can't change role for Admin") g.db.execute( ''' UPDATE "user" SET role=%s WHERE id=%s ''', [body['role'], body['id']]) g.db.commit() return OK("OK")
def delete(self, project_id, user_id): owner_id = g.token['user']['id'] if user_id == owner_id: abort(404) g.db.execute(''' DELETE FROM collaborator WHERE user_id = %s AND project_id = %s ''', [user_id, project_id]) g.db.commit() return OK('Successfully removed user')
def post(self, project_id): ''' Change projects visibility ''' b = request.get_json() private = b['private'] g.db.execute( ''' UPDATE project SET public = %s WHERE id = %s ''', [not private, project_id]) return OK('updated visibility')
def get(self, project_id, build_id): jobs = g.db.execute_many_dict(''' SELECT id FROM job WHERE build_id = %s AND project_id = %s ''', [build_id, project_id]) for j in jobs: g.db.execute(''' INSERT INTO abort(job_id) VALUES(%s) ''', [j['id']]) g.db.commit() return OK('Aborted all jobs')
def post(self, project_id): b = request.get_json() username = b['username'] user = g.db.execute_one_dict(''' SELECT * FROM "user" WHERE username = %s ''', [username]) if not user: abort(400, "User not found") g.db.execute(''' INSERT INTO collaborator (project_id, user_id) VALUES(%s, %s) ON CONFLICT DO NOTHING ''', [project_id, user['id']]) g.db.commit() return OK('Successfully added user')