Commit Graph

127 Commits

Author SHA1 Message Date
Kevin Chung
22a0c0b007 Add a decorator for redirecting users if their profile isn't complete (#1933)
* Redirect users and teams whose profiles are incomplete to complete their profile
* Closes #1926
2021-07-29 02:11:54 -04:00
Kevin Chung
0dbe008011 Small fixes from making CSV examples (#1963)
* Closes #1958
2021-07-27 17:03:27 -04:00
Kevin Chung
0ba70aa92d Improved CSV exports (#1960)
* Closes #1940
* Create Scoreboard CSV export with support for custom fields
* Create Users CSV export with support for custom fields
* Create Teams CSV export with support for custom fields
2021-07-26 02:20:54 -04:00
Kevin Chung
61507bb12a Add CSV importing feature (#1922)
* Closes #1888 
* Adds code to import CSVs for challenges, users, and teams
2021-06-26 18:04:14 -04:00
Kevin Chung
614f086540 Allow Page editor to write HTML directly (#1915)
* Works on #1493 
* Adds a new column for Pages to specify format
* Separate out `build_html` into `build_html` and `build_markdown`
* Add config variables into pages: `ctf_name`, `ctf_description`, `ctf_start`, `ctf_end`, `ctf_freeze`
  * The time variables are represented as ISO8601 timestamps
2021-06-17 10:33:01 -04:00
Kevin Chung
021e151946 Switch python-geoacumen to python-geoacumen-city (#1911)
* Closes #1872 
* IP Addresses in the Admin Panel will now show the city of the IP address as well as the country
2021-06-11 17:30:27 -04:00
Kevin Chung
2f3409d887 Add fix for MLC configs in config.ini (#1909) 2021-06-11 14:57:19 -04:00
Kevin Chung
3cb67a97ec Bump pybluemonday version to 0.0.6 and allow HTML comments in sanitized output (#1908)
* Bump pybluemonday version to 0.0.6 
* Allow HTML comments in sanitized output
* Closes #1906
2021-06-11 10:21:03 -04:00
Ife Lawal
c31916057f Confirmed REST API does delete directories in s3 bucket. The local filesystem didn't though and that was updated. Closes #1758 (#1876)
- Deleting uploads under the Filesystem upload provider will now delete the parent folder as well as the target file
- Closes #1758
2021-06-06 23:21:38 -04:00
Mike Merrill
8646f2384c Update geoip.py (#1896)
Added error handling in case `IP_ADDR_LOOKUP.get(addr)` fails.
2021-05-28 11:03:56 -04:00
Kevin Chung
88c53f3510 Make expired token error message more useful (#1851)
* Make expired token error message more useful
2021-03-25 11:59:59 -04:00
Kevin Chung
a045114251 Use pybluemonday instead of lxml for html sanitization (#1837)
* Use `pybluemonday` instead of `lxml` for html sanitization
* Fix boolean optional configs in `config.py`
* Closes #1835
2021-03-19 01:29:49 -04:00
Kevin Chung
8de9819bd4 3.3.0 (#1833)
# 3.3.0 / UNRELEASED

**General**

- Don't require a team for viewing challenges if Challenge visibility is set to public
- Add a `THEME_FALLBACK` config to help develop themes. See **Themes** section for details.

**API**

- Implement a faster `/api/v1/scoreboard` endpoint in Teams Mode
- Add the `solves` item to both `/api/v1/challenges` and `/api/v1/challenges/[challenge_id]` to more easily determine how many solves a challenge has
- Add the `solved_by_me` item to both `/api/v1/challenges` and `/api/v1/challenges/[challenge_id]` to more easily determine if the current account has solved the challenge
- Prevent admins from deleting themselves through `DELETE /api/v1/users/[user_id]`
- Add length checking to some sensitive fields in the Pages and Challenges schemas
- Fix issue where `PATCH /api/v1/users[user_id]` returned a list instead of a dict
- Fix exception that occured on demoting admins through `PATCH /api/v1/users[user_id]`
- Add `team_id` to `GET /api/v1/users` to determine if a user is already in a team

**Themes**

- Add a `THEME_FALLBACK` config to help develop themes.
  - `THEME_FALLBACK` will configure CTFd to try to find missing theme files in the default built-in `core` theme.
  - This makes it easier to develop themes or use incomplete themes.
- Allow for one theme to reference and inherit from another theme through approaches like `{% extends "core/page.html" %}`
- Allow for the automatic date rendering format to be overridden by specifying a `data-time-format` attribute.
- Add styling for the `<blockquote>` element.
- Fix scoreboard table identifier to switch between User/Team depending on configured user mode
- Switch to using Bootstrap's scss in `core/main.scss` to allow using Bootstrap variables
- Consolidate Jinja error handlers into a single function and better handle issues where error templates can't be found

**Plugins**

- Set plugin migration version after successful migrations
- Fix issue where Page URLs injected into the navbar were relative instead of absolute

**Admin Panel**

- Add User standings as well as Teams standings to the admin scoreboard when in Teams Mode
- Add a UI for adding members to a team from the team's admin page
- Add ability for admins to disable public team creation
- Link directly to users who submitted something in the submissions page if the CTF is in Teams Mode
- Fix Challenge Requirements interface in Admin Panel to not allow empty/null requirements to be added
- Fixed an issue where config times (start, end, freeze times) could not be removed
- Fix an exception that occurred when demoting an Admin user
- Adds a temporary hack for re-enabling Javascript snippets in Flag editor templates. (See #1779)

**Deployment**

- Install `python3-dev` instead of `python-dev` in apt
- Bump lxml to 4.6.2
- Bump pip-compile to 5.4.0

**Miscellaneous**

- Cache Docker builds more by copying and installing Python dependencies before copying CTFd
- Change the default emails slightly and rework confirmation email page to make some recommendations clearer
- Use `examplectf.com` as testing/development domain instead of `ctfd.io`
- Fixes issue where user's name and email would not appear in logs properly
- Add more linting by also linting with `flake8-comprehensions` and `flake8-bugbear`
2021-03-18 18:08:46 -04:00
Kevin Chung
a3dbecdd18 Link directly to users from the submissions page in teams mode (#1823)
* Links directly to users who submitted something in the submissions page if the CTF is in teams mode. 
* Closes #1813
2021-03-16 15:32:38 -04:00
Alper Berber
4125e7c00c Fixed registration and confirmation logs (#1734)
* Fixes issue where user's name and email would not appear in logs properly
* Closes #1706
2021-03-06 15:56:12 -05:00
Kevin Chung
5611c47487 1002 improve email content (#1804)
* Change the default emails slightly and rework confirmation email page to make some recommendations clearer
* Works a little more on #1002
2021-02-18 16:09:10 -05:00
Kevin Chung
ab4c37b31f Add a lower parameter to the plugin upgrade() function to help importing (#1755)
- The plugin `upgrade()` function now accepts a `lower` parameter which specifies what lower revision should be used to start from.
  - This is used to support plugin migrations during import so that we can import data directly at the point that the import was taken from
  - `lower="current"` means to use the current revision and `lower=None` would mean to use the absolute base revision (e.g. plugin's first installation)
  - By default this doesn't change `upgrade()` behavior
2020-12-06 22:24:37 -05:00
Kevin Chung
cb5ba26bdb Miscellaneous Fixes (#1752)
* Update CHANGELOG 
* Add `registered_only` decorator
* Make team invites redirect to `/register` if you're unauthed
2020-12-04 14:10:36 -05:00
Kevin Chung
d9975f307c Mark 3.2.0 (#1748)
# 3.2.0 / unreleased

**General**

- Add Team invites.
  - Team invites are links containing a token that allow a user to join a team without knowing the team password
  - Captains can generate invite tokens for their teams
  - Admins can generate Team invite links as well
- Improved Team handling
  - Prevent team joining while already on a team
  - Return 403 instead of 200 for team join/create errors
  - Allow team captains whose teams haven't done anything to disband their team
- Allow for uploading navbar logo, favicon, and index page banner during initial setup
- Fixed issue in teams mode where a user couldn't unlock a hint despite their team having enough points
  - The fix for this is essentially to allow the user's points to go negative
- Imports have been made more stable
  - This is primarily done by killing MySQL processes that are locking metadta
  - This is a subpar approach but it seems to be the only solution to avoid a metadata lock in MySQL. This approach did not appear to be needed under Postgres or SQLite
- Update some migrations to first check if a table already exists.

**API**

- Addition of `POST /api/v1/teams/me/members` to generate invite tokens for teams
- Fixed an issue in `POST /api/v1/awards` where CTFd would 500 when a user could not be found by the provided `user_id`
- `POST /api/v1/unlocks` in teams mode now uses the team's score to determine if a user can purchase a hint
  - Properly check for existing unlocks in teams mode in `POST /api/v1/unlocks`
- `/api/v1/notifications` and `/api/v1/notifications/[notification_id]` now have an html parameter which specifies the rendered content of the notification content

**Themes**

- Added syntax highlighting to challenge descriptions, pages, hints, notifications, comments, and markdown editors
  - This is done with `highlight.js` which has been added to `package.json`
- Fix notifications to properly fix/support Markdown and HTML notifications
  - Notifications SQL Model now has an html propery
  - Notifications API schemas now has an html field
- Removed MomentJS (see https://momentjs.com/docs/#/-project-status/) in favor of dayjs
  - dayjs is mostly API compatible with MomentJS. The only major changes were:
    - dayjs always uses browser local time so you don't need to call `.local()`
    - dayjs segments out some MomentJS functionality into plugins which need to be imported in before using those features
- Fixed issue in `challenge.html` where the current attempt count would have a typo
- Fixed issue in `challenge.html` where the max attempts for a challenge would not show if it was set to 1
- Edit donut charts to have easier to read legends and labels
- Make data zoom bars thinner and more transparent

**Plugins**

- Don't run `db.create_all()` as much during plugin upgrade or during imports
  - By avoiding this we can let alembic and migrations do more of the table creation work but this means that plugins specifically opt into `app.db.create_all()` and will not implicitly get it through `upgrade()`.
  - This means plugins that run `upgrade()` without a migrations folder (no idea who would do this really) will need to upgrade their code.

**Admin Panel**

- Add Favicon uploading to the Admin Panel
- Move Logo uploading to the Theme tab in the Admin Panel
- The challenge left side bar tabs have been rewritten into VueJS components.
  - This fixes a number of issues with the consistency of what data is deleted/edited in the challenge editor
  - This also prevents having to refresh the page in most challenge editing situations
- Fixed a possible bug where the update available alert wouldn't go away on server restart
- Examples for regex flags are now provided
- Wrong submissions has been renamed to Incorrect Submissions
- Graphs in the Admin Statistics page will now scroll with mouse wheel to improve browsing large datasets

**Deployment**

- A restart policy set to `always` has been added to nginx in docker-compose
- Rename `requirements.txt` to `requirements.in` and generate `requirements.txt` using `pip-tools` under Python 3.6
- `UPLOAD_PROVIDER` no longer has a default `filesystem` set in config.ini. Instead it is defaulted through `config.py`

**Miscellaneous**

- The `psycopg2` dependency in development.txt has been removed in favor of `psycopg2-binary` which was updated to 2.8.6
- The `moto` dependency in development.txt has been updated to 1.3.16
- Add `pip-tools` to `development.txt`
- Add `import_ctf` and `export_ctf` commands to `manage.py` and deprecate `import.py` and `export.py`
- Override the `MAIL_SERVER` config with the `TESTING_MAIL_SERVER` envvar during tests
- `ping` events in the notification event handler have been fixed to not send duplicates
2020-12-01 16:09:31 -05:00
Frank
1883c62cf5 reduce ping events (Fix #1685) (#1699)
Closes #1685
2020-11-18 20:27:48 -05:00
Kevin Chung
44a588869e Increase timeout for update check (#1726)
* Increase timeout for update check from 0.1 seconds to 3 seconds
* Closes #1678
2020-11-18 02:54:15 -05:00
Kevin Chung
4cd4d0cb92 Add the ability to override the sender header of email via SMTP (#1657)
* Add the ability to override the sender header of email via SMTP with the `MAILSENDER_ADDR` config value
* Closes #1644
2020-09-20 23:54:19 -04:00
Kevin Chung
9264e96428 Mark 3.1.0 (#1634)
# 3.1.0 / 2020-09-08

**General**

- Loosen team password confirmation in team settings to also accept the team captain's password to make it easier to change the team password
- Adds the ability to add custom user and team fields for registration/profile settings.
- Improve Notifications pubsub events system to use a subscriber per server instead of a subscriber per browser. This should improve the reliability of CTFd at higher load and make it easier to deploy the Notifications system

**Admin Panel**

- Add a comments functionality for admins to discuss challenges, users, teams, pages
- Adds a legal section in Configs where users can add a terms of service and privacy policy
- Add a Custom Fields section in Configs where admins can add/edit custom user/team fields
- Move user graphs into a modal for Admin Panel

**API**

- Add `/api/v1/comments` to manipulate and create comments

**Themes**

- Make scoreboard caching only cache the score table instead of the entire page. This is done by caching the specific template section. Refer to #1586, specifically the changes in `scoreboard.html`.
- Add rel=noopener to external links to prevent tab napping attacks
- Change the registration page to reference links to Terms of Service and Privacy Policy if specified in configuration

**Miscellaneous**

- Make team settings modal larger in the core theme
- Update tests in Github Actions to properly test under MySQL and Postgres
- Make gevent default in serve.py and add a `--disable-gevent` switch in serve.py
- Add `tenacity` library for retrying logic
- Add `pytest-sugar` for slightly prettier pytest output
- Add a `listen()` method to `CTFd.utils.events.EventManager` and `CTFd.utils.events.RedisEventManager`.
  - This method should implement subscription for a CTFd worker to whatever underlying notification system there is. This should be implemented with gevent or a background thread.
  - The `subscribe()` method (which used to implement the functionality of the new `listen()` function) now only handles passing notifications from CTFd to the browser. This should also be implemented with gevent or a background thread.
2020-09-08 00:08:35 -04:00
Kevin Chung
976b191b53 Fix submission search (#1605)
* Fix submission searching in Admin Panel
2020-08-14 12:20:41 -04:00
Kevin Chung
f4c9d1e2e8 1569 submission filter by challenge (#1590)
* Allow the Admin Panel Submissions page to filter by Account IDs, Challenge IDs, and Challenge Names
* Deprecate `CTFd.api.v1.helpers.models.build_model_filters` and wrap it to `CTFd.utils.helpers.models.build_model_filters`
* Clean up some miscellaneous Submissions code 
* Closes #1569
2020-08-09 03:40:11 -04:00
Kevin Chung
5d7e0e39c7 1580 fix hidden admin scores (#1581)
* Fix issue where admins could not see user graphs/api data if score visibility was set to hidden
* Closes #1580
2020-08-04 13:23:46 -04:00
Kevin Chung
4d4097a267 Add channel to update check and use new endpoint (#1568)
* Add a channel key to update check and use a new GET based update check endpoint
* Bump `black` version to `19.10b0`
2020-07-24 01:59:14 -04:00
Kevin Chung
98b9dda58c Fix sending emails when CTF name contains colons (#1560)
* Fixes issue with sending emails if the CTF name has a colon
* Closes #1558
2020-07-21 19:53:28 -04:00
Kevin Chung
a1e4f15bdc Make HTML sanitization an optional setting (#1556)
* Add new `HTML_SANITIZATION` server config to make HTML sanitization optional
2020-07-19 21:56:53 -04:00
Kevin Chung
559306ee4f Allow comments in HTML (#1555)
* Re-allow HTML comments in sanitized HTML
2020-07-19 21:07:20 -04:00
Kevin Chung
421dfc169a Allow bootstrap data attributes through the HTML sanitizer (#1553)
* Allow bootstrap data attributes through the HTML sanitizer
2020-07-19 17:19:33 -04:00
Kevin Chung
adc70fb320 3.0.0a1 (#1523)
Alpha release of CTFd v3. 

# 3.0.0a1 / 2020-07-01

**General**

- CTFd is now Python 3 only
- Render markdown with the CommonMark spec provided by `cmarkgfm`
- Render markdown stripped of any malicious JavaScript or HTML.
  - This is a significant change from previous versions of CTFd where any HTML content from an admin was considered safe.
- Inject `Config`, `User`, `Team`, `Session`, and `Plugin` globals into Jinja
- User sessions no longer store any user-specific attributes.
  - Sessions only store the user's ID, CSRF nonce, and an hmac of the user's password
  - This allows for session invalidation on password changes
- The user facing side of CTFd now has user and team searching
- GeoIP support now available for converting IP addresses to guessed countries

**Admin Panel**

- Use EasyMDE as an improved description/text editor for Markdown enabled fields.
- Media Library button now integrated into EasyMDE enabled fields
- VueJS now used as the underlying implementation for the Media Library
- Fix setting theme color in Admin Panel
- Green outline border has been removed from the Admin Panel

**API**

- Significant overhauls in API documentation provided by Swagger UI and Swagger json
- Make almost all API endpoints provide filtering and searching capabilities
- Change `GET /api/v1/config/<config_key>` to return structured data according to ConfigSchema

**Themes**

- Themes now have access to the `Configs` global which provides wrapped access to `get_config`.
  - For example, `{{ Configs.ctf_name }}` instead of `get_ctf_name()` or `get_config('ctf_name')`
- Themes must now specify a `challenge.html` which control how a challenge should look.
- The main library for charts has been changed from Plotly to Apache ECharts.
- Forms have been moved into wtforms for easier form rendering inside of Jinja.
  - From Jinja you can access forms via the Forms global i.e. `{{ Forms }}`
  - This allows theme developers to more easily re-use a form without having to copy-paste HTML.
- Themes can now provide a theme settings JSON blob which can be injected into the theme with `{{ Configs.theme_settings }}`
- Core theme now includes the challenge ID in location hash identifiers to always refer the right challenge despite duplicate names

**Plugins**

- Challenge plugins have changed in structure to better allow integration with themes and prevent obtrusive Javascript/XSS.
  - Challenge rendering now uses `challenge.html` from the provided theme.
  - Accessing the challenge view content is now provided by `/api/v1/challenges/<challenge_id>` in the `view` section. This allows for HTML to be properly sanitized and rendered by the server allowing CTFd to remove client side Jinja rendering.
  - `challenge.html` now specifies what's required and what's rendered by the theme. This allows the challenge plugin to avoid having to deal with aspects of the challenge besides the description and input.
  - A more complete migration guide will be provided when CTFd v3 leaves beta
- Display current attempt count in challenge view when max attempts is enabled
- `get_standings()`, `get_team_stanadings()`, `get_user_standings()` now has a fields keyword argument that allows for specificying additional fields that SQLAlchemy should return when building the response set.
  - Useful for gathering additional data when building scoreboard pages
- Flags can now control the message that is shown to the user by raising `FlagException`
- Fix `override_template()` functionality

**Deployment**

- Enable SQLAlchemy's `pool_pre_ping` by default to reduce the likelihood of database connection issues
- Mailgun email settings are now deprecated. Admins should move to SMTP email settings instead.
- Postgres is now considered a second class citizen in CTFd. It is tested against but not a main database backend. If you use Postgres, you are entirely on your own with regards to supporting CTFd.
- Docker image now uses Debian instead of Alpine. See https://github.com/CTFd/CTFd/issues/1215 for rationale.
- `docker-compose.yml` now uses a non-root user to connect to MySQL/MariaDB
- `config.py` should no longer be editting for configuration, instead edit `config.ini` or the environment variables in `docker-compose.yml`
2020-07-01 12:06:05 -04:00
Kevin Chung
98bf240cc1 Improve response times of /api/v1/scoreboard significantly (#1470)
* Improve response times of `/api/v1/scoreboard` significantly by avoiding hitting the database to get every team member's score
* Fix issue where a hidden/banned user's score could be revealed as a member of a team

From tests I was able to cut this down from 11s to 0.5s. This endpoint also will still be heavily cached which should improve performance for a lot of users.
2020-06-04 02:37:10 -04:00
Kevin Chung
7cf6d2b43a 2.5.0 dev (#1453)
2.5.0 / 2020-06-02
==================

**General**
* Use a session invalidation strategy inspired by Django. Newly generated user sessions will now include a HMAC of the user's password. When the user's password is changed by someone other than the user the previous HMACs will no longer be valid and the user will be logged out when they next attempt to perform an action.
* A user and team's place, and score are now cached and invalidated on score changes.

**API**
* Add `/api/v1/challenges?view=admin` to allow admin users to see all challenges regardless of their visibility state
* Add `/api/v1/users?view=admin` to allow admin users to see all users regardless of their hidden/banned state
* Add `/api/v1/teams?view=admin` to allow admin users to see all teams regardless of their hidden/banned state
* The scoreboard endpoints `/api/v1/scoreboard` & `/api/v1/scoreboard/top/[count]` should now be more performant because score and place for Users/Teams are now cached

**Deployment**
* `docker-compose` now provides a basic nginx configuration and deploys nginx on port 80

**Miscellaneous**
* The `get_config` and `get_page` config utilities now use SQLAlchemy Core instead of SQLAlchemy ORM for slight speedups
* Update Flask-Migrate to 2.5.3 and regenerate the migration environment. Fixes using `%` signs in database passwords.
2020-06-02 11:22:01 -04:00
Kevin Chung
80df88f25d Revert "Use a ThreadPoolExecutor to concurrently store files dut string import (#1427)" (#1428)
This reverts commit 2245df85f4.
2020-05-21 02:15:16 -04:00
Kevin Chung
2245df85f4 Use a ThreadPoolExecutor to concurrently store files during import (#1427)
* Use a `ThreadPoolExecutor` to concurrently store files during import
2020-05-20 22:03:35 -04:00
Kevin Chung
ba887e8952 1422 block imports without db folder (#1424)
* Don't allow backups to be imported if they do not have a `db` folder
* Closes #1422
2020-05-20 15:52:09 -04:00
Kevin Chung
5618f0d04c 1406 plugin migrations improvements (#1420)
* Handle plugin migrations during CTF import
* Closes #1406
2020-05-19 21:21:31 -04:00
Kevin Chung
148bdccf26 Improve import_ctf reliability (#1419)
* Improve `import_ctf()` reliability by closing all connections before dropping & recreating database
* Close database session in IP tracking code in failure situations
2020-05-18 11:46:15 -04:00
Kevin Chung
2769dc6367 Have EventManagers yield before timer code to force SSE response head… (#1400)
* EventManagers should send an initial ping event to force `text/event-steam` header to be set
2020-05-13 19:33:01 -04:00
Kevin Chung
97a221aa24 Fix an issue where session id no longer exists 2020-05-05 19:41:45 -04:00
Kevin Chung
625c17db30 Invalidate any previously cached attributes on user login 2020-05-03 20:47:25 -04:00
Kevin Chung
c47955ff4f Always record IP usage on non-GET and clean up HTML 2020-04-30 21:10:43 -04:00
Kevin Chung
01f2d50a34 Rewrite IP tracking code to only return recent IPs. Move IPs into a modal for admin panel. 2020-04-30 20:32:26 -04:00
Kevin Chung
2f1b3265f8 Run make lint 2020-04-30 14:39:42 -04:00
Kevin Chung
b3b654bf03 Rebase 2.4.0-dev 2020-04-30 03:21:13 -04:00
Kevin Chung
0bd6c0d958 Merge remote-tracking branch 'origin/2.4.0-dev' into cache-user-ips-for-tracker 2020-04-30 03:10:31 -04:00
Kevin Chung
87895918f5 Fix tracker code to fix tests 2020-04-30 02:45:12 -04:00
Kevin Chung
232a4468b0 Run format 2020-04-30 02:22:44 -04:00
Kevin Chung
e99f4f11a5 Merge remote-tracking branch 'origin/2.4.0-dev' into is_admin_func_cache_hit 2020-04-30 00:31:21 -04:00