mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 05:54:19 +01:00
Add a description field to api tokens and make api tokens start with a 'ctfd_' prefix (#2337)
* Add a description field for API tokens * API tokens now start with a `ctfd_` prefix to make them easier to identify * Closes #2184
This commit is contained in:
@@ -85,11 +85,14 @@ class TokenList(Resource):
|
||||
def post(self):
|
||||
req = request.get_json()
|
||||
expiration = req.get("expiration")
|
||||
description = req.get("description")
|
||||
if expiration:
|
||||
expiration = datetime.datetime.strptime(expiration, "%Y-%m-%d")
|
||||
|
||||
user = get_current_user()
|
||||
token = generate_user_token(user, expiration=expiration)
|
||||
token = generate_user_token(
|
||||
user, expiration=expiration, description=description
|
||||
)
|
||||
|
||||
# Explicitly use admin view so that user's can see the value of their token
|
||||
schema = TokenSchema(view="admin")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from flask import session
|
||||
from flask_babel import lazy_gettext as _l
|
||||
from wtforms import PasswordField, SelectField, StringField
|
||||
from wtforms import PasswordField, SelectField, StringField, TextAreaField
|
||||
from wtforms.fields.html5 import DateField, URLField
|
||||
|
||||
from CTFd.constants.languages import SELECT_LANGUAGE_LIST
|
||||
@@ -50,4 +50,5 @@ def SettingsForm(*args, **kwargs):
|
||||
|
||||
class TokensForm(BaseForm):
|
||||
expiration = DateField(_l("Expiration"))
|
||||
description = TextAreaField("Usage Description")
|
||||
submit = SubmitField(_l("Generate"))
|
||||
|
||||
@@ -916,6 +916,7 @@ class Tokens(db.Model):
|
||||
db.DateTime,
|
||||
default=lambda: datetime.datetime.utcnow() + datetime.timedelta(days=30),
|
||||
)
|
||||
description = db.Column(db.Text)
|
||||
value = db.Column(db.String(128), unique=True)
|
||||
|
||||
user = db.relationship("Users", foreign_keys="Tokens.user_id", lazy="select")
|
||||
|
||||
@@ -9,8 +9,16 @@ class TokenSchema(ma.ModelSchema):
|
||||
dump_only = ("id", "expiration", "type")
|
||||
|
||||
views = {
|
||||
"admin": ["id", "type", "user_id", "created", "expiration", "value"],
|
||||
"user": ["id", "type", "created", "expiration"],
|
||||
"admin": [
|
||||
"id",
|
||||
"type",
|
||||
"user_id",
|
||||
"created",
|
||||
"expiration",
|
||||
"description",
|
||||
"value",
|
||||
],
|
||||
"user": ["id", "type", "created", "expiration", "description"],
|
||||
}
|
||||
|
||||
def __init__(self, view=None, *args, **kwargs):
|
||||
|
||||
@@ -81,7 +81,10 @@
|
||||
<b>{{ form.expiration.label }}</b>
|
||||
{{ form.expiration(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<b>{{ form.description.label }}</b>
|
||||
{{ form.description(class="form-control", rows="3") }}
|
||||
</div>
|
||||
<div class="form-group text-right">
|
||||
{{ form.submit(class="btn btn-md btn-primary btn-outlined") }}
|
||||
</div>
|
||||
@@ -96,6 +99,7 @@
|
||||
<tr>
|
||||
<td class="text-center"><b>Created</b></td>
|
||||
<td class="text-center"><b>Expiration</b></td>
|
||||
<td class="text-center"><b>Description</b></td>
|
||||
<td class="text-center"><b>Delete</b></td>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -104,6 +108,7 @@
|
||||
<tr>
|
||||
<td><span data-time="{{ token.created | isoformat }}"></span></td>
|
||||
<td><span data-time="{{ token.expiration | isoformat }}"></span></td>
|
||||
<td><span>{{ token.description | default('', true) }}</span></td>
|
||||
<td class="text-center">
|
||||
<span class="delete-token" role="button" data-token-id="{{ token.id }}">
|
||||
<i class="btn-fa fas fa-times"></i>
|
||||
|
||||
@@ -34,13 +34,15 @@ def logout_user():
|
||||
session.clear()
|
||||
|
||||
|
||||
def generate_user_token(user, expiration=None):
|
||||
def generate_user_token(user, expiration=None, description=None):
|
||||
temp_token = True
|
||||
while temp_token is not None:
|
||||
value = hexencode(os.urandom(32))
|
||||
value = "ctfd_" + hexencode(os.urandom(32))
|
||||
temp_token = UserTokens.query.filter_by(value=value).first()
|
||||
|
||||
token = UserTokens(user_id=user.id, expiration=expiration, value=value)
|
||||
token = UserTokens(
|
||||
user_id=user.id, expiration=expiration, description=description, value=value
|
||||
)
|
||||
db.session.add(token)
|
||||
db.session.commit()
|
||||
return token
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
"""Add description column to tokens table
|
||||
|
||||
Revision ID: 9e6f6578ca84
|
||||
Revises: 0def790057c1
|
||||
Create Date: 2023-06-21 23:22:34.179636
|
||||
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "9e6f6578ca84"
|
||||
down_revision = "0def790057c1"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column("tokens", sa.Column("description", sa.Text(), nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column("tokens", "description")
|
||||
Reference in New Issue
Block a user