-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
583 additions
and
167 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Flask config file | ||
# | ||
# This file is loaded by flask to app.config. | ||
# It can overload flask configuration (https://flask.palletsprojects.com/en/3.0.x/config/) | ||
# and it load custom config values for the app. | ||
# All variable names must be upper case for flask to load them. | ||
# | ||
|
||
# Flask debug mode | ||
# set to true for development | ||
DEBUG = false | ||
|
||
# Flask tests | ||
# set to true for development | ||
TESTING = false | ||
|
||
# Secret key used for session encryption | ||
# set to long random string for security | ||
SECRET_KEY = '<secret>' # CHANGE THIS! | ||
|
||
[OAUTH] | ||
|
||
# Client ID created in OIDC provider (keycloak) | ||
CLIENT_ID = '<client-id>' | ||
|
||
# Client secret from OIDC provider (keycloak) | ||
CLIENT_SECRET = '<client-secret>' | ||
|
||
# URL for oauth client to pull information about openid configuration | ||
SERVER_METADATA_URL = 'https://<oidc-url>/realms/master/.well-known/openid-configuration' | ||
|
||
[GUNICORN] | ||
|
||
# The number of worker processes for handling requests | ||
THREADS = 2 | ||
|
||
# The number of worker threads in each process for handling requests | ||
WORKERS = 4 |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Repos config file | ||
# | ||
# Declares all repositories in this app. Each repository is its own section | ||
# specified by [reponame] with listed config values. | ||
# | ||
|
||
[fykos37] # reponame | ||
git_path='[email protected]:FYKOS/fykos37.git' # ssh address of git repository, string | ||
allowed_roles=['fksdb-fykos'] # array of allowed users, array of strings | ||
build_cmd='make -k all' # build command, string | ||
image_version='latest' # docker image version of buildtools, string, optional (default 'latest') | ||
submodules=false # does repo have submodules, bool, optional (default false) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
CherryPy | ||
GitPython | ||
Flask | ||
AuthLib | ||
requests | ||
gunicorn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
from flask import Flask, abort, redirect, render_template, send_from_directory, session, url_for | ||
import configparser | ||
import os | ||
import tomllib | ||
|
||
from repository import Repository | ||
from oauth import isLoggedIn, registerAuthRoutes, requireLogin | ||
|
||
# TODO run using gunicorn for more threads | ||
|
||
app = Flask(__name__, | ||
static_folder='static', | ||
template_folder='templates') | ||
|
||
# load config | ||
app.config.from_file("/data/config/config.toml", load=tomllib.load, text=False) | ||
|
||
registerAuthRoutes(app) | ||
|
||
# load repos | ||
#reposConfig = configparser.ConfigParser() | ||
#reposConfig.read('/data/config/repos.ini') | ||
with open('/data/config/repos.toml', 'rb') as file: | ||
reposConfig = tomllib.load(file) | ||
|
||
repos = {repo: Repository(repo, '/data/repos/', reposConfig[repo]) for repo in reposConfig} | ||
|
||
# automatically inject user to every rendered template | ||
@app.context_processor | ||
def inject_user(): | ||
return dict(user = session.get('user')) | ||
|
||
# | ||
# routes | ||
# | ||
|
||
@app.route('/') | ||
def index(): | ||
if isLoggedIn(): | ||
return render_template('index.html.jinja', repos=repos) | ||
return render_template('signin.html.jinja') | ||
|
||
@app.route('/info/<string:repoName>') | ||
@requireLogin | ||
def info(repoName): | ||
if repoName not in repos: | ||
abort(404) | ||
repo = repos[repoName] | ||
if not repo.checkAccess(): | ||
abort(401) | ||
return render_template('info.html.jinja', repo=repoName, log=repo.logger.getLogs()) | ||
|
||
@app.route('/buildlog/<string:repoName>') | ||
@requireLogin | ||
def buildLog(repoName): | ||
if repoName not in repos: | ||
abort(404) | ||
repo = repos[repoName] | ||
if not repo.checkAccess(): | ||
abort(401) | ||
return render_template('buildlog.html.jinja', repo=repoName, log=repo.logger.getBuildLog()) | ||
|
||
@app.route('/build/<string:repoName>') | ||
@requireLogin | ||
def build(repoName): | ||
if repoName not in repos: | ||
abort(404) | ||
repo = repos[repoName] | ||
if not repo.checkAccess(): | ||
abort(401) | ||
|
||
repo.execute() | ||
|
||
return redirect(url_for('index')) | ||
|
||
# TODO redirect to url with trailing / when showing folder for correct html hrefs | ||
@app.route('/<string:repoName>/') | ||
@app.route('/<string:repoName>/<path:path>') | ||
@requireLogin | ||
def repository(repoName, path=''): | ||
if repoName not in repos: | ||
abort(404) | ||
repo = repos[repoName] | ||
if not repo.checkAccess(): | ||
abort(401) | ||
|
||
repoDir = os.path.normpath(os.path.join('/data/repos', repoName)) | ||
normalizedPath = os.path.normpath(path) | ||
targetPath = os.path.normpath(os.path.join(repoDir, normalizedPath)) | ||
|
||
# check that listed directory is child of repository directory | ||
# for potencial directory travelsal attacks | ||
if not targetPath.startswith(repoDir): | ||
abort(404) | ||
|
||
if not os.path.exists(targetPath): | ||
abort(404) | ||
|
||
if os.path.isdir(targetPath): | ||
directoryContent = next(os.walk(targetPath)) | ||
# filter directories and files starting with . | ||
dirs=[d for d in sorted(directoryContent[1]) if not d.startswith('.')] | ||
files=[f for f in sorted(directoryContent[2]) if not f.startswith('.')] | ||
|
||
return render_template('listdir.html.jinja', path=os.path.normpath(os.path.join(repoName, normalizedPath)), repo=repoName, dirs=dirs, files=files) | ||
|
||
if os.path.isfile(targetPath): | ||
return send_from_directory(repoDir, normalizedPath) | ||
|
||
abort(404) | ||
|
||
|
||
if __name__ == '__main__': | ||
app.run(host='0.0.0.0', port=8080) |
Oops, something went wrong.