mirror of https://github.com/EasyCTF/librectf
Port to Docker
This commit is contained in:
parent
4225cc4dde
commit
fe32273dcc
|
@ -8,3 +8,6 @@
|
|||
__pycache__
|
||||
*.pyc
|
||||
ubuntu-xenial-16.04-cloudimg-console.log
|
||||
|
||||
ctf-data
|
||||
.direnv
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
CREATE DATABASE `app`;
|
||||
CREATE USER `app`@'%' IDENTIFIED BY 'hellosu';
|
||||
GRANT ALL PRIVILEGES ON app.* TO app@'%';
|
||||
|
||||
CREATE DATABASE `minio`;
|
||||
CREATE USER minio@'%' IDENTIFIED BY 'hellosu';
|
||||
GRANT ALL PRIVILEGES ON minio.* TO minio@'%';
|
|
@ -0,0 +1,37 @@
|
|||
version: "3"
|
||||
|
||||
services:
|
||||
nginx:
|
||||
build: nginx
|
||||
|
||||
app:
|
||||
build: server
|
||||
depends_on: [db]
|
||||
ports: [3000:5000]
|
||||
volumes:
|
||||
- ./server:/app
|
||||
environment:
|
||||
- SECRET_KEY=ad88fec19a7641e5de308e45dd4fa1c5
|
||||
- DATABASE_URL=mysql://app:hellosu@db:3306/app
|
||||
|
||||
- WAIT_HOSTS=db:3306
|
||||
- WAIT_HOSTS_TIMEOUT=300
|
||||
- WAIT_SLEEP_INTERVAL=10
|
||||
- WAIT_HOST_CONNECT_TIMEOUT=30
|
||||
|
||||
db:
|
||||
image: mariadb
|
||||
expose: [3306]
|
||||
volumes:
|
||||
- ./db/init.d:/docker-entrypoint-initdb.d
|
||||
- ./ctf-data/mariadb:/var/lib/mysql
|
||||
environment:
|
||||
- MARIADB_ROOT_PASSWORD=45694fd9e39afc4a3597bc2797620e15
|
||||
|
||||
files:
|
||||
image: minio/minio
|
||||
volumes:
|
||||
- ./ctf-data/minio:/data
|
||||
|
||||
redis:
|
||||
image: redis
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "flake-utils",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1653936696,
|
||||
"narHash": "sha256-M6bJShji9AIDZ7Kh7CPwPBPb/T7RiVev2PAcOi4fxDQ=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ce6aa13369b667ac2542593170993504932eb836",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
pythonPackages = pkgs.python310Packages;
|
||||
in {
|
||||
devShell = pkgs.mkShell {
|
||||
buildInputs = (with pkgs; [ libmysqlclient ])
|
||||
++ (with pythonPackages; [ poetry ]);
|
||||
|
||||
SECRET_KEY = "ad88fec19a7641e5de308e45dd4fa1c5";
|
||||
};
|
||||
});
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
FROM nginx
|
|
@ -0,0 +1,20 @@
|
|||
FROM python:3
|
||||
ENV FLASK_DEBUG=1
|
||||
|
||||
RUN apt-get update -y && apt-get install -y --no-install-recommends \
|
||||
libmariadb-dev \
|
||||
;
|
||||
RUN pip install poetry
|
||||
|
||||
ENV WAIT_VERSION 2.7.2
|
||||
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/$WAIT_VERSION/wait /wait
|
||||
RUN chmod +x /wait
|
||||
|
||||
RUN mkdir -p /app
|
||||
WORKDIR /app
|
||||
|
||||
COPY poetry.lock .
|
||||
COPY pyproject.toml .
|
||||
RUN poetry install
|
||||
|
||||
CMD ["sh", "-c", "/wait && poetry run flask db upgrade && poetry run flask run --host 0.0.0.0"]
|
|
@ -8,7 +8,7 @@ from flask_login import current_user
|
|||
|
||||
|
||||
def create_app(config=None):
|
||||
app = Flask(__name__, static_folder="assets", static_path="/assets")
|
||||
app = Flask(__name__, static_folder="assets", static_url_path="/assets")
|
||||
hostname = socket.gethostname()
|
||||
|
||||
if not config:
|
||||
|
@ -16,10 +16,11 @@ def create_app(config=None):
|
|||
config = Config()
|
||||
app.config.from_object(config)
|
||||
|
||||
from easyctf.objects import cache, db, login_manager, sentry
|
||||
from easyctf.objects import cache, db, login_manager, sentry, migrate
|
||||
import easyctf.models
|
||||
cache.init_app(app)
|
||||
db.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
login_manager.init_app(app)
|
||||
if app.config.get("ENVIRONMENT") != "development":
|
||||
sentry.init_app(app, logging=True, level=logging.WARNING)
|
||||
|
|
Before Width: | Height: | Size: 434 KiB After Width: | Height: | Size: 434 KiB |
|
@ -4,7 +4,7 @@ import sys
|
|||
import logging
|
||||
|
||||
import pathlib
|
||||
from werkzeug.contrib.cache import RedisCache
|
||||
from cachelib import RedisCache
|
||||
|
||||
|
||||
class CTFCache(RedisCache):
|
||||
|
|
|
@ -7,8 +7,7 @@ from sqlalchemy import and_
|
|||
from wtforms import ValidationError
|
||||
from wtforms.fields import (BooleanField, FloatField, HiddenField,
|
||||
IntegerField, StringField, SubmitField,
|
||||
TextAreaField)
|
||||
from wtforms.fields.html5 import DateTimeLocalField
|
||||
TextAreaField, DateTimeLocalField)
|
||||
from wtforms.validators import InputRequired, NumberRange, Optional
|
||||
|
||||
from easyctf.models import Problem
|
||||
|
|
|
@ -6,7 +6,7 @@ from wtforms.fields import (BooleanField, FileField, IntegerField,
|
|||
PasswordField, RadioField, StringField,
|
||||
SubmitField)
|
||||
from wtforms.validators import Email, EqualTo, InputRequired, Length, Optional
|
||||
from wtforms.widgets.html5 import NumberInput
|
||||
from wtforms.widgets import NumberInput
|
||||
|
||||
from easyctf.forms.validators import UsernameLengthValidator
|
||||
from easyctf.models import User
|
||||
|
|
|
@ -620,15 +620,15 @@ class Team(db.Model):
|
|||
def size(self):
|
||||
return len(self.members)
|
||||
|
||||
@hybrid_property
|
||||
# @hybrid_property
|
||||
@cache.memoize(timeout=120)
|
||||
def observer(self):
|
||||
return User.query.filter(and_(User.tid == self.tid, User.level != USER_REGULAR)).count()
|
||||
|
||||
@observer.expression
|
||||
@cache.memoize(timeout=120)
|
||||
def observer(self):
|
||||
return db.session.query(User).filter(User.tid == self.tid and User.level != USER_REGULAR).count()
|
||||
# @observer.expression
|
||||
# @cache.memoize(timeout=120)
|
||||
# def observer(self):
|
||||
# return db.session.query(User).filter(User.tid == self.tid and User.level != USER_REGULAR).count()
|
||||
|
||||
@hybrid_property
|
||||
def prop_points(self):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from random import SystemRandom
|
||||
|
||||
from flask_caching import Cache
|
||||
from flask_migrate import Migrate
|
||||
from flask_login import LoginManager
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from raven.contrib.flask import Sentry
|
||||
|
@ -10,3 +11,4 @@ cache = Cache()
|
|||
login_manager = LoginManager()
|
||||
db = SQLAlchemy()
|
||||
sentry = Sentry()
|
||||
migrate = Migrate()
|
||||
|
|
|
@ -281,7 +281,10 @@ def register_user(name, email, username, password, level, admin=False, **kwargs)
|
|||
setattr(new_user, key, value)
|
||||
code = generate_string()
|
||||
new_user.email_token = code
|
||||
send_verification_email(username, email, url_for("users.verify", code=code, _external=True))
|
||||
|
||||
# TODO: Config for this
|
||||
# send_verification_email(username, email, url_for("users.verify", code=code, _external=True))
|
||||
|
||||
db.session.add(new_user)
|
||||
db.session.commit()
|
||||
return new_user
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
[tool.poetry]
|
||||
name = "easyctf-platform"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Michael Zhang <mail@mzhang.io>"]
|
||||
license = "AGPL-3.0"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
bcrypt = "^4.0.1"
|
||||
celery = "^5.2.7"
|
||||
coverage = "^6.5.0"
|
||||
cryptography = "^38.0.4"
|
||||
Flask = "^2.2.2"
|
||||
Flask-Breadcrumbs = "^0.5.1"
|
||||
Flask-Caching = "^2.0.1"
|
||||
Flask-Celery-Helper = "^1.1.0"
|
||||
flask-csp = "^0.10"
|
||||
Flask-Login = "^0.6.2"
|
||||
Flask-Migrate = "^4.0.0"
|
||||
Flask-Script = "^2.0.6"
|
||||
flask-sqlalchemy = "^3.0.2"
|
||||
Flask-WTF = "^1.0.1"
|
||||
gitdb = "^4.0.10"
|
||||
GitPython = "^3.1.29"
|
||||
markdown2 = "^2.4.6"
|
||||
mysqlclient = "^2.1.1"
|
||||
onetimepass = "^1.0.1"
|
||||
paramiko = "^2.12.0"
|
||||
passlib = "^1.7.4"
|
||||
pathlib = "^1.0.1"
|
||||
Pillow = "^9.3.0"
|
||||
pycryptodome = "^3.16.0"
|
||||
PyQRCode = "^1.2.1"
|
||||
pytest = "^7.2.0"
|
||||
PyYAML = "^6.0"
|
||||
rauth = "^0.7.3"
|
||||
raven = {extras = ["flask"], version = "^6.10.0"}
|
||||
redis = "^4.3.5"
|
||||
requests = "^2.28.1"
|
||||
SQLAlchemy = "^1.4.44"
|
||||
WTForms-Components = "^0.10.5"
|
||||
Werkzeug = "^2.2.2"
|
||||
cachelib = "^0.9.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
|
@ -1,33 +0,0 @@
|
|||
bcrypt
|
||||
celery
|
||||
coverage
|
||||
cryptography==2.1.4
|
||||
flask
|
||||
flask-breadcrumbs
|
||||
flask-caching
|
||||
flask-celery-helper
|
||||
flask-csp
|
||||
flask-login
|
||||
flask-migrate
|
||||
flask-script
|
||||
flask-sqlalchemy
|
||||
flask-wtf
|
||||
gitdb
|
||||
gitpython
|
||||
markdown2
|
||||
mysqlclient
|
||||
onetimepass
|
||||
paramiko
|
||||
passlib
|
||||
pathlib
|
||||
pillow
|
||||
pycryptodome
|
||||
pyqrcode
|
||||
pytest
|
||||
pyyaml
|
||||
rauth
|
||||
raven[flask]
|
||||
redis
|
||||
requests
|
||||
sqlalchemy==1.1.0b3
|
||||
wtforms_components
|
Loading…
Reference in New Issue