mirror of https://github.com/JohnHammond/CTFd.git
Use strings for key type (#409)
* Store key_type as string in the database * Give keys plugin the ability to know where the modals are stored and pass this information to the clientselenium-screenshot-testing
parent
b4bdef966c
commit
6117699260
|
@ -199,11 +199,13 @@ def admin_get_values(chalid, prop):
|
|||
chal_keys = Keys.query.filter_by(chal=challenge.id).all()
|
||||
json_data = {'keys': []}
|
||||
for x in chal_keys:
|
||||
key_class = get_key_class(x.key_type)
|
||||
json_data['keys'].append({
|
||||
'id': x.id,
|
||||
'key': x.flag,
|
||||
'type': x.key_type,
|
||||
'type_name': get_key_class(x.key_type).name
|
||||
'type_name': key_class.name,
|
||||
'templates': key_class.templates,
|
||||
})
|
||||
return jsonify(json_data)
|
||||
elif prop == 'tags':
|
||||
|
@ -257,7 +259,7 @@ def admin_create_chal():
|
|||
db.session.add(chal)
|
||||
db.session.flush()
|
||||
|
||||
flag = Keys(chal.id, request.form['key'], int(request.form['key_type[0]']))
|
||||
flag = Keys(chal.id, request.form['key'], request.form['key_type[0]'])
|
||||
if request.form.get('keydata'):
|
||||
flag.data = request.form.get('keydata')
|
||||
db.session.add(flag)
|
||||
|
|
|
@ -9,13 +9,23 @@ admin_keys = Blueprint('admin_keys', __name__)
|
|||
|
||||
|
||||
@admin_keys.route('/admin/key_types', methods=['GET'])
|
||||
@admin_keys.route('/admin/key_types/<key_id>', methods=['GET'])
|
||||
@admins_only
|
||||
def admin_key_types():
|
||||
def admin_key_types(key_id=None):
|
||||
if key_id is None:
|
||||
data = {}
|
||||
for class_id in KEY_CLASSES:
|
||||
data[class_id] = KEY_CLASSES.get(class_id).name
|
||||
|
||||
return jsonify(data)
|
||||
else:
|
||||
key_class = get_key_class(key_id)
|
||||
data = {
|
||||
'id': key_class.id,
|
||||
'name': key_class.name,
|
||||
'templates': key_class.templates
|
||||
}
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@admin_keys.route('/admin/keys', defaults={'keyid': None}, methods=['POST', 'GET'])
|
||||
|
@ -25,14 +35,15 @@ def admin_keys_view(keyid):
|
|||
if request.method == 'GET':
|
||||
if keyid:
|
||||
saved_key = Keys.query.filter_by(id=keyid).first_or_404()
|
||||
|
||||
key_class = get_key_class(saved_key.key_type)
|
||||
json_data = {
|
||||
'id': saved_key.id,
|
||||
'key': saved_key.flag,
|
||||
'data': saved_key.data,
|
||||
'chal': saved_key.chal,
|
||||
'type': saved_key.key_type,
|
||||
'type_name': get_key_class(saved_key.key_type).name
|
||||
'type_name': key_class.name,
|
||||
'templates': key_class.templates,
|
||||
}
|
||||
|
||||
return jsonify(json_data)
|
||||
|
@ -40,7 +51,7 @@ def admin_keys_view(keyid):
|
|||
chal = request.form.get('chal')
|
||||
flag = request.form.get('key')
|
||||
data = request.form.get('keydata')
|
||||
key_type = int(request.form.get('key_type'))
|
||||
key_type = request.form.get('key_type')
|
||||
if not keyid:
|
||||
k = Keys(chal, flag, key_type)
|
||||
k.data = data
|
||||
|
|
|
@ -127,7 +127,7 @@ class Files(db.Model):
|
|||
class Keys(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
chal = db.Column(db.Integer, db.ForeignKey('challenges.id'))
|
||||
key_type = db.Column(db.Integer)
|
||||
key_type = db.Column(db.String(80))
|
||||
flag = db.Column(db.Text)
|
||||
data = db.Column(db.Text)
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ def init_plugins(app):
|
|||
:return:
|
||||
"""
|
||||
modules = glob.glob(os.path.dirname(__file__) + "/*")
|
||||
blacklist = {'keys', '__pycache__'}
|
||||
blacklist = {'__pycache__'}
|
||||
for module in modules:
|
||||
module_name = os.path.basename(module)
|
||||
if os.path.isdir(module) and module_name not in blacklist:
|
||||
|
|
|
@ -48,13 +48,13 @@
|
|||
<div class="col-md-2">
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="key_type[0]" value="0" checked>
|
||||
<input type="radio" name="key_type[0]" value="static" checked>
|
||||
Static
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="key_type[0]" value="1">
|
||||
<input type="radio" name="key_type[0]" value="regex">
|
||||
Regex
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -317,11 +317,13 @@ $('#create-key').click(function(e){
|
|||
$('#create-keys-select').change(function(){
|
||||
var key_type_name = $(this).find("option:selected").text();
|
||||
|
||||
$.get(script_root + '/themes/admin/static/js/templates/keys/'+key_type_name +'/'+key_type_name+'.hbs', function(template_data){
|
||||
$.get(script_root + '/admin/key_types/' + key_type_name, function(key_data){
|
||||
$.get(script_root + key_data.templates.create, function(template_data){
|
||||
var template = Handlebars.compile(template_data);
|
||||
$("#create-keys-entry-div").html(template());
|
||||
$("#create-keys-button-div").show();
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from CTFd.plugins import register_plugin_assets_directory
|
||||
|
||||
import re
|
||||
import string
|
||||
import hmac
|
||||
|
@ -6,6 +8,7 @@ import hmac
|
|||
class BaseKey(object):
|
||||
id = None
|
||||
name = None
|
||||
templates = {}
|
||||
|
||||
@staticmethod
|
||||
def compare(self, saved, provided):
|
||||
|
@ -15,6 +18,10 @@ class BaseKey(object):
|
|||
class CTFdStaticKey(BaseKey):
|
||||
id = 0
|
||||
name = "static"
|
||||
templates = { # Handlebars templates used for key editing & viewing
|
||||
'create': '/plugins/keys/assets/static/create-static-modal.hbs',
|
||||
'update': '/plugins/keys/assets/static/edit-static-modal.hbs',
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def compare(saved, provided):
|
||||
|
@ -29,6 +36,10 @@ class CTFdStaticKey(BaseKey):
|
|||
class CTFdRegexKey(BaseKey):
|
||||
id = 1
|
||||
name = "regex"
|
||||
templates = { # Handlebars templates used for key editing & viewing
|
||||
'create': '/plugins/keys/assets/regex/create-regex-modal.hbs',
|
||||
'update': '/plugins/keys/assets/regex/edit-regex-modal.hbs',
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def compare(saved, provided):
|
||||
|
@ -37,8 +48,8 @@ class CTFdRegexKey(BaseKey):
|
|||
|
||||
|
||||
KEY_CLASSES = {
|
||||
0: CTFdStaticKey,
|
||||
1: CTFdRegexKey
|
||||
'static': CTFdStaticKey,
|
||||
'regex': CTFdRegexKey
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,3 +58,7 @@ def get_key_class(class_id):
|
|||
if cls is None:
|
||||
raise KeyError
|
||||
return cls
|
||||
|
||||
|
||||
def load(app):
|
||||
register_plugin_assets_directory(app, base_path='/plugins/keys/assets/')
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="modal-body">
|
||||
<form method="POST" action="{{ script_root }}/admin/keys/{{id}}" style="text-align:center">
|
||||
<input type="text" id="key-data" class="form-control" name="key" value="{{key}}" placeholder="Enter regex key data">
|
||||
<input type="hidden" id="key-type" name="key_type" value="1">
|
||||
<input type="hidden" id="key-type" name="key_type" value="regex">
|
||||
<input type="hidden" id="key-id">
|
||||
<hr>
|
||||
<div class="row">
|
|
@ -6,7 +6,7 @@
|
|||
<div class="modal-body">
|
||||
<form method="POST" action="{{ script_root }}/admin/keys/{{id}}" style="text-align:center">
|
||||
<input type="text" id="key-data" class="form-control" name="key" value="{{key}}" placeholder="Enter static key data">
|
||||
<input type="hidden" id="key-type" name="key_type" value="0">
|
||||
<input type="hidden" id="key-type" name="key_type" value="static">
|
||||
<input type="hidden" id="key-id">
|
||||
<hr>
|
||||
<div class="row">
|
|
@ -22,8 +22,8 @@ String.prototype.hashCode = function() {
|
|||
};
|
||||
|
||||
function load_edit_key_modal(key_id, key_type_name) {
|
||||
$.get(script_root + '/themes/admin/static/js/templates/keys/'+key_type_name+'/edit-'+key_type_name+'-modal.hbs', function(template_data){
|
||||
$.get(script_root + '/admin/keys/' + key_id, function(key_data){
|
||||
$.get(script_root + key_data.templates.update, function(template_data){
|
||||
$('#edit-keys').empty();
|
||||
var template = Handlebars.compile(template_data);
|
||||
key_data['script_root'] = script_root;
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,58 @@
|
|||
"""Use strings for key types
|
||||
|
||||
Revision ID: e62fd69bd417
|
||||
Revises: 7e9efd084c5a
|
||||
Create Date: 2017-10-14 14:56:14.215349
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'e62fd69bd417'
|
||||
down_revision = '7e9efd084c5a'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
bind = op.get_bind()
|
||||
url = str(bind.engine.url)
|
||||
if url.startswith('mysql'):
|
||||
op.alter_column('keys', 'key_type',
|
||||
existing_type=sa.INTEGER(),
|
||||
type_=sa.String(length=80),
|
||||
existing_nullable=True)
|
||||
op.execute("UPDATE `keys` set key_type='static' WHERE key_type=0")
|
||||
op.execute("UPDATE `keys` set key_type='regex' WHERE key_type=1")
|
||||
elif url.startswith('postgres'):
|
||||
op.alter_column('keys', 'key_type',
|
||||
existing_type=sa.INTEGER(),
|
||||
type_=sa.String(length=80),
|
||||
existing_nullable=True,
|
||||
postgresql_using="CASE WHEN key_type=0 THEN 'static' WHEN key_type=1 THEN 'regex' ELSE NULL END"
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
bind = op.get_bind()
|
||||
url = str(bind.engine.url)
|
||||
if url.startswith('mysql'):
|
||||
op.execute("UPDATE `keys` set key_type=0 WHERE key_type='static'")
|
||||
op.execute("UPDATE `keys` set key_type=1 WHERE key_type='regex'")
|
||||
op.alter_column('keys', 'key_type',
|
||||
existing_type=sa.String(length=80),
|
||||
type_=sa.INTEGER(),
|
||||
existing_nullable=True)
|
||||
elif url.startswith('postgres'):
|
||||
op.alter_column('keys', 'key_type',
|
||||
existing_type=sa.String(length=80),
|
||||
type_=sa.INTEGER(),
|
||||
existing_nullable=True,
|
||||
postgresql_using="CASE WHEN key_type='static' THEN 0 WHEN key_type='regex' THEN 1 ELSE NULL END"
|
||||
)
|
||||
# ### end Alembic commands ###
|
|
@ -222,7 +222,7 @@ if __name__ == '__main__':
|
|||
word = gen_word()
|
||||
db.session.add(Challenges(word, gen_sentence(), gen_value(), gen_category()))
|
||||
db.session.commit()
|
||||
db.session.add(Keys(x + 1, word, 0))
|
||||
db.session.add(Keys(x + 1, word, 'static'))
|
||||
db.session.commit()
|
||||
|
||||
# Generating Files
|
||||
|
|
|
@ -109,7 +109,7 @@ def gen_file():
|
|||
pass
|
||||
|
||||
|
||||
def gen_flag(db, chal, flag='flag', key_type=0):
|
||||
def gen_flag(db, chal, flag='flag', key_type='static'):
|
||||
key = Keys(chal, flag, key_type)
|
||||
db.session.add(key)
|
||||
db.session.commit()
|
||||
|
|
Loading…
Reference in New Issue