Skip to content

Commit

Permalink
merge into master (#54)
Browse files Browse the repository at this point in the history
* update to conform with flake8/PEP8 | #47

* Update README.md

* Create CODE_OF_CONDUCT.md (#51)

* 1. psf/black formatting with travis checks, 2. adjust docs, create CONTRIBUTING.md, 3. helper fns for creating admin pass and secret key by itself on run

create admin pass and secret key by itself on run

* Update README.md

* Update CONTRIBUTING.md

* create admin pass and secret key by itself on run

* better docs

* fix pwd truncation
  • Loading branch information
eshaan7 authored Apr 19, 2020
1 parent f07e323 commit 85a4b6a
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 80 deletions.
18 changes: 16 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,21 @@

## Style Guide

Keeping to a consistent code style throughout the project makes it easier to contribute and collaborate. Please stick to the guidelines in PEP8, [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) and the Google Style Guide unless there’s a very good reason not to.
Keeping to a consistent code style throughout the project makes it easier to contribute and collaborate. Please stick to the guidelines in [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) and the Google Style Guide unless there’s a very good reason not to.

### Before submitting a Pull Request, please run these 2 commands locally

```bash
$ black .
```

```bash
$ flake8 src/ flake8 . ---max-line-length=88 --show-source --statistics
```

if flake8 shows any errors or warnings, please fix the changes in a new commit and squash all the commits into one before submitting the PR.

> Guide on squashing commits: [here](https://github.com/wprig/wprig/wiki/How-to-squash-commits)
## Contact

Expand Down Expand Up @@ -80,4 +94,4 @@ See: [Issues](https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework/issues) and th
- [x] Use Flask Blueprints
- [x] Finalize black theme?
- [x] Error messages not appearing in `/submit`
- [x] Implement `machine.html` to server a page where one can download/serve machines
- [x] Implement `machine.html` to server a page where one can download/serve machines
41 changes: 41 additions & 0 deletions INSTALLATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Installation / How To Use

### Requirements

* Tested on `Python 3.8.2`
* Python Packages: [`src/requirements.txt`](src/requirements.txt).
* OS Packages: PostgreSQL version 11 or greater, `libpq-dev`, `python3-dev` packages. Please refer [here](https://tutorials.technology/solved_errors/9-Error-pg_config-executable-not-found.html).

### Build locally and run

1. Git clone the repo and `cd ` into it

```bash
$ git clone https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework
$ cd RTB-CTF-Framework/
```
2. Create `virtual environment` to deal with dependencies and requirements.

```bash
$ virtualenv -p /usr/bin/python3 venv
$ source venv/bin/activate
$ cd src/
```

3. With `virtual environment` activated, install requirements, init db and run !

```bash
[venv]$ pip install -r requirements.txt
[venv]$ python create_db.py # Only required on first run
[venv]$ python run.py
```

> Warning: If you make any change to [`config.py`](https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework/blob/master/src/FlaskRTBCTF/config.py) logging/config class/score settings. It's highly recommended to create a new DB instance.
### Docker

> Note: The Docker support is not tested for production yet. It's recommended to use Heroku for production.
```bash
$ docker-compose up
```
88 changes: 23 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RootTheBox CTF Framework

<p >
<p>
<a href="https://inventory.rawsec.ml/" target="_blank">
<img height="26px" alt="Rawsec's CyberSecurity Inventory" src="https://inventory.rawsec.ml/img/badges/Rawsec-inventoried-FF5050_for-the-badge.svg">
</a>
Expand All @@ -26,7 +26,7 @@ The main purpose of this project is to serve as a scoring engine and CTF manager

A live demo of the app is available at: <https://rtblivedemo.herokuapp.com/>.

You can login and mess around as 2 users: `admin:admin` and `test:test` (i.e. username:password combinations)
You can login and mess around as the admin user `admin:admin` (i.e. username:password combinations) or register your own.

## Features

Expand All @@ -43,84 +43,41 @@ The main purpose of this project is to serve as a scoring engine and CTF manager
* Flask-blueprints for modularity and clean codebase,
* Flask-admin for Admin views and easy realtime management,
* Flask-SQLAlchemy for SQL models,
* Flask-wtf for forms,
* Flask-mail for mail service.

## Deployment

### Heroku
* Flask-login for session handling,
* Flask-wtf for responsive forms,
* Flask-mail for mail service,
* Flask-bcrypt for password hashing and security,

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
## Build locally

or do it manually,
Please see [INSTALLATION.md](INSTALLATION.md).

1. Create your heroku app using `heroku` cli tool.

Follow the official guide by Heroku: https://devcenter.heroku.com/articles/getting-started-with-python#prepare-the-app
## Host Your Own CTF In 5 minutes with Heroku

2. Provision Database add-on.

Add the following add on to your new app: https://elements.heroku.com/addons/heroku-postgresql

3. Creating database instance. In your heroku app directory,
Using this is as simple as anything.

```bash
$ heroku run bash
[heroku]$ python create_db.py
```
4. Your app should be live now. You can run `heroku open` to open it in browser.

### Docker
1. Fork the `master` branch and clone your fork,

```bash
$ docker-compose up
```

## How To Use

### Requirements

* Tested on `Python 3.8.2`
* Python Packages: [`src/requirements.txt`](src/requirements.txt).
* OS Packages: PostgreSQL version 11 or greater, `libpq-dev`, `python3-dev` packages. Please refer [here](https://tutorials.technology/solved_errors/9-Error-pg_config-executable-not-found.html).

### Installation and first run

1. Git clone the repo and `cd ` into it

```bash
$ git clone https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework
$ git clone https://github.com/<your_github_username>/RTB-CTF-Framework
$ cd RTB-CTF-Framework/
```
2. Create `virtual environment` to deal with dependencies and requirements.

```bash
$ virtualenv -p /usr/bin/python3 venv
$ source venv/bin/activate
$ cd src/
```

3. With `virtual environment` activated, install requirements, init db and run !

```bash
[venv]$ pip install -r requirements.txt
[venv]$ python create_db.py # Only required on first run
[venv]$ python run.py
```

### Configuration For Your CTF
2. Configure your CTF settings (such as name, running time) in [`config.py`](https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework/blob/master/src/FlaskRTBCTF/config.py).

Using this as simple as anything.
3. In the `app.json`, change the `repository` key's value to match your fork's URL.

1. Just configure your CTF settings in [`config.py`](https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework/blob/master/src/FlaskRTBCTF/config.py).
4. Push these changes to the remote of your fork.

2. When you run [`create_db.py`](https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework/blob/master/src/create_db.py), a strong and random 16 char password for the **admin** user is created and set in the environment variable `ADMIN_PASS`. On Heroku, you can reveal this password from your application's dashboard settings.
5. Visit your Fork's GitHub URL in the browser and click on the following **Deploy to Heroku** button.

> Note: A psuedo-random password for the **admin** user would be created and set in the config variable `ADMIN_PASS`. On Heroku, you can reveal this password from your application's dashboard settings. Same for the Flask application's `SECRET_KEY`.
3. See database instance creation steps under How To Use.
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)

Bonus: You can manage the database CRUD operations from admin views GUI as well as issue notifications.
#### Yay! Now you have a customized instance of the RTB-CTF-Framework live on Heroku. 🎉

> Warning: If you make any change to [`config.py`](https://github.com/abs0lut3pwn4g3/RTB-CTF-Framework/blob/master/src/FlaskRTBCTF/config.py) logging/config class/score settings. It's highly recommended to create a new DB instance.
> Bonus: You can manage the database CRUD operations from admin views GUI; change machine settings, issue notifications to users, etc.
## Contributing

Expand All @@ -133,7 +90,6 @@ Bonus: You can manage the database CRUD operations from admin views GUI as well
</a>
</p>


##### 👨 Project Owner

- Eshaan Bansal ([github](https://github.com/eshaan7), [linkedin](https://www.linkedin.com/in/eshaan7/))
Expand All @@ -150,6 +106,8 @@ For further guidelines, Please refer to [CONTRIBUTING.md](CONTRIBUTING.md)

## Screenshots

> Why look at static pictures, when you can use a demo ? Visit: <https://rtblivedemo.herokuapp.com/>.
<img src="screenshots/home_ss.png" width=400 />
<img src="screenshots/scoreboard_ss.png" width=400 />
<img src="screenshots/machine_ss.png" width=400 />
Expand Down
10 changes: 10 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
"url": "heroku/python"
}
],
"env": {
"SECRET_KEY": {
"description": "Flask app instance's SECRET_KEY",
"generator": "secret"
},
"ADMIN_PASS": {
"description": "Administrator password",
"generator": "secret"
}
},
"scripts": {
"postdeploy": "python3 src/create_db.py"
}
Expand Down
1 change: 1 addition & 0 deletions runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-3.8.2
8 changes: 4 additions & 4 deletions src/FlaskRTBCTF/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
import secrets


def handle_secret_key():
sk = os.environ.get("SECRET_KEY", None)
def handle_secret_key(default="you-will-never-guess"):
sk = os.environ.get("SECRET_KEY", default)
if not sk:
sk = secrets.token_hex(16)
os.environ["SECRET_KEY"] = sk
return sk


def handle_admin_pass():
passwd = os.environ.get("ADMIN_PASS", None)
def handle_admin_pass(default="admin"):
passwd = os.environ.get("ADMIN_PASS", default)
if not passwd:
passwd = secrets.token_hex(16)
os.environ["ADMIN_PASS"] = passwd
Expand Down
6 changes: 3 additions & 3 deletions src/FlaskRTBCTF/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class Machine(db.Model):

class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(40), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
username = db.Column(db.String(24), unique=True, nullable=False)
email = db.Column(db.String(88), unique=True, nullable=False)
password = db.Column(db.String(64), nullable=False)
isAdmin = db.Column(db.Boolean, default=False)
score = db.relationship("Score", backref="user", lazy=True, uselist=False)
if LOGGING:
Expand Down
18 changes: 12 additions & 6 deletions src/FlaskRTBCTF/users/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@

class RegistrationForm(FlaskForm):
username = StringField(
"Username", validators=[DataRequired(), Length(min=4, max=20)]
"Username", validators=[DataRequired(), Length(min=4, max=24)]
)
email = StringField(
"Email", validators=[DataRequired(), Email(), Length(min=6, max=88)]
)
password = PasswordField(
"Password", validators=[DataRequired(), Length(min=4, max=32)]
)
email = StringField("Email", validators=[DataRequired(), Email()])
password = PasswordField("Password", validators=[DataRequired()])
confirm_password = PasswordField(
"Confirm Password", validators=[DataRequired(), EqualTo("password")]
)
Expand All @@ -32,7 +36,7 @@ def validate_email(self, email):

class LoginForm(FlaskForm):
username = StringField(
"Username", validators=[DataRequired(), Length(min=4, max=20)]
"Username", validators=[DataRequired(), Length(min=4, max=24)]
)
password = PasswordField("Password", validators=[DataRequired()])
remember = BooleanField("Remember Me")
Expand All @@ -41,7 +45,7 @@ class LoginForm(FlaskForm):

class UpdateAccountForm(FlaskForm):
username = StringField(
"Username", validators=[DataRequired(), Length(min=4, max=20)]
"Username", validators=[DataRequired(), Length(min=4, max=24)]
)
email = StringField("Email", validators=[DataRequired(), Email()])
submit = SubmitField("Update")
Expand Down Expand Up @@ -76,7 +80,9 @@ def validate_email(self, email):


class ResetPasswordForm(FlaskForm):
password = PasswordField("Password", validators=[DataRequired()])
password = PasswordField(
"Password", validators=[DataRequired(), Length(min=4, max=48)]
)
confirm_password = PasswordField(
"Confirm Password", validators=[DataRequired(), EqualTo("password")]
)
Expand Down

0 comments on commit 85a4b6a

Please sign in to comment.