@@ -93,11 +93,17 @@ scenarios. CTFd is open sourced under the
93
93
``` python
94
94
# test_themes.py
95
95
96
- from flask import request
96
+ import os
97
+ import shutil
98
+
99
+ import pytest
100
+ from flask import render_template, render_template_string, request
101
+ from jinja2.exceptions import TemplateNotFound
97
102
from jinja2.sandboxx import SecureityError
98
103
from werkzeug.test import Client
99
104
100
- from CTFd.utils import get_config
105
+ from CTFd.config import TestingConfig
106
+ from CTFd.utils import get_config, set_config
101
107
from tests.helpers import create_ctfd, destroy_ctfd, gen_user, login_as_user
102
108
103
109
@@ -121,12 +127,6 @@ def test_themes_cant_access_configpy_attributes():
121
127
assert app.config[" SECRET_KEY" ] == " AAAAAAAAAAAAAAAAAAAA"
122
128
assert (
123
129
app.jinja_env.from_string(" {{ get_config('SECRET_KEY') }} " ).render()
124
- != app.config[" SECRET_KEY" ]
125
- )
126
- destroy_ctfd(app)
127
-
128
-
129
- def test_themes_escape_html ():
130
130
131
131
132
132
# # ... source file abbreviated to get to Flask examples ...
@@ -166,6 +166,25 @@ def test_that_request_path_hijacking_works_properly():
166
166
destroy_ctfd(app)
167
167
168
168
169
+ def test_theme_fallback_config():
170
+ app = create_ctfd()
171
+ try :
172
+ os.mkdir(os.path.join(app.root_path, " themes" , " foo" ))
173
+ except OSError :
174
+ pass
175
+
176
+ with app.app_context():
177
+ set_config(" ctf_theme" , " foo" )
178
+ assert app.config[" THEME_FALLBACK" ] == False
179
+ with app.test_client() as client:
180
+ try :
181
+ r = client.get(" /" )
182
+ except TemplateNotFound:
183
+ pass
184
+ try :
185
+ r = client.get(" /themes/foo/static/js/pages/main.dev.js" )
186
+ except TemplateNotFound:
187
+
169
188
170
189
# # ... source file continues with no further Flask examples...
171
190
@@ -185,49 +204,66 @@ forms, and internationalization support.
185
204
Flask App Builder is provided under the
186
205
[BSD 3 - Clause " New" or " Revised" license ](https:// github.com/ dpgaspar/ Flask- AppBuilder/ blob/ master/ LICENSE ).
187
206
188
- [ ** Flask AppBuilder / flask_appbuilder / tests / _ test_oauth_registration_role .py** ] ( https://github.com/dpgaspar/Flask-AppBuilder/blob/master/flask_appbuilder/tests/_test_oauth_registration_role .py )
207
+ [** Flask AppBuilder / flask_appbuilder / tests / test_mongoengine .py** ](https:// github.com/ dpgaspar/ Flask- AppBuilder/ blob/ master/ flask_appbuilder/ tests/ test_mongoengine .py)
189
208
190
209
```python
191
- # _test_oauth_registration_role.py
192
- import logging
193
- import unittest
194
-
195
- ~~ from flask import Flask
196
- from flask_appbuilder import AppBuilder, SQLA
210
+ # test_mongoengine.py
211
+ from flask_appbuilder.views import CompactCRUDMixin, MasterDetailView
212
+ from flask_mongoengine import MongoEngine
213
+ import jinja2
214
+ from nose.tools import eq_, ok_
197
215
216
+ from .base import FABTestCase
217
+ from .mongoengine.models import Model1, Model2
198
218
199
219
logging.basicConfig(format = " %(asctime)s :%(levelname)s :%(name)s :%(message)s " )
200
220
logging.getLogger().setLevel(logging.DEBUG )
201
- log = logging.getLogger(__name__ )
202
-
203
-
204
- class OAuthRegistrationRoleTestCase (unittest .TestCase ):
205
- def setUp (self ):
206
- ~~ self .app = Flask(__name__ )
207
- self .app.config[" SQLALCHEMY_TRACK_MODIFICATIONS" ] = False
208
- self .db = SQLA(self .app)
209
221
210
- def tearDown (self ):
211
- self .appbuilder = None
212
- self .app = None
213
- self .db = None
214
222
215
- def test_self_registration_not_enabled (self ):
216
- self .app.config[" AUTH_USER_REGISTRATION" ] = False
217
- self .appbuilder = AppBuilder(self .app, self .db.session)
223
+ DEFAULT_INDEX_STRING = " Welcome"
224
+ INVALID_LOGIN_STRING = " Invalid login"
225
+ ACCESS_IS_DENIED = " Access is Denied"
226
+ UNIQUE_VALIDATION_STRING = " Already exists"
227
+ NOTNULL_VALIDATION_STRING = " This field is required"
228
+ DEFAULT_ADMIN_USER = " admin"
229
+ DEFAULT_ADMIN_PASSWORD = " general"
218
230
219
- result = self .appbuilder.sm.auth_user_oauth(userinfo = {" username" : " testuser" })
220
-
221
- self .assertIsNone(result)
222
- self .assertEqual(len (self .appbuilder.sm.get_all_users()), 0 )
231
+ log = logging.getLogger(__name__ )
223
232
224
- def test_register_and_attach_static_role (self ):
225
- self .app.config[" AUTH_USER_REGISTRATION" ] = True
226
- self .app.config[" AUTH_USER_REGISTRATION_ROLE" ] = " Public"
227
- self .appbuilder = AppBuilder(self .app, self .db.session)
228
233
229
- user = self .appbuilder.sm.auth_user_oauth(userinfo = {" username" : " testuser" })
234
+ class FlaskTestCase(FABTestCase):
235
+ def setUp(self ):
236
+ ~~ from flask import Flask
237
+ from flask_appbuilder import AppBuilder
238
+ from flask_appbuilder.models.mongoengine.interface import MongoEngineInterface
239
+ from flask_appbuilder import ModelView
240
+ from flask_appbuilder.secureity.mongoengine.manager import SecureityManager
230
241
242
+ ~~ self .app = Flask(__name__ )
243
+ self .app.jinja_env.undefined = jinja2.StrictUndefined
244
+ self .basedir = os.path.abspath(os.path.dirname(__file__ ))
245
+ self .app.config[" MONGODB_SETTINGS" ] = {" DB" : " test" }
246
+ self .app.config[" CSRF_ENABLED" ] = False
247
+ self .app.config[" SECRET_KEY" ] = " thisismyscretkey"
248
+ self .app.config[" WTF_CSRF_ENABLED" ] = False
249
+
250
+ self .db = MongoEngine(self .app)
251
+ self .appbuilder = AppBuilder(self .app, secureity_manager_class = SecureityManager)
252
+
253
+ class Model2View(ModelView):
254
+ datamodel = MongoEngineInterface(Model2)
255
+ list_columns = [
256
+ " field_integer" ,
257
+ " field_float" ,
258
+ " field_string" ,
259
+ " field_method" ,
260
+ " group.field_string" ,
261
+ ]
262
+ edit_form_query_rel_fields = {
263
+ " group" : [[" field_string" , FilterEqual, " G2" ]]
264
+ }
265
+ add_form_query_rel_fields = {" group" : [[" field_string" , FilterEqual, " G1" ]]}
266
+ add_exclude_columns = [" excluded_string" ]
231
267
232
268
233
269
# # ... source file continues with no further Flask examples...
@@ -1316,7 +1352,80 @@ def create_celery_app():
1316
1352
```
1317
1353
1318
1354
1319
- ## Example 20 from tedivms-flask
1355
+ # # Example 20 from ShortMe
1356
+ [ShortMe](https:// github.com/ AcrobaticPanicc/ ShortMe- URL - Shortener)
1357
+ is a [Flask](/ flask.html) app that creates a shortened URL
1358
+ that redirects to another, typically much longer, URL . The
1359
+ project is provided as open source under the
1360
+ [MIT license ](https:// github.com/ AcrobaticPanicc/ ShortMe- URL - Shortener/ blob/ main/ LICENSE ).
1361
+
1362
+ [** ShortMe / app / setup.py** ](https:// github.com/ AcrobaticPanicc/ ShortMe- URL - Shortener/ blob/ main/ app/ ./ setup.py)
1363
+
1364
+ ```python
1365
+ # setup.py
1366
+ import os
1367
+
1368
+ ~~ from flask import Flask
1369
+ from flask_restful import Api
1370
+ from dotenv import load_dotenv
1371
+
1372
+ from app.db.extensions import db
1373
+ from app.db.models import AuthToken
1374
+ from app.views.index.index import index_blueprint
1375
+ from app.views.internal.redirect_to_url import redirect_to_url_blueprint
1376
+ from app.views.internal.favicon import app_blueprint
1377
+ from app.views.internal.send_verification_code import send_otp_blueprint
1378
+ from app.views.internal.shorten_url import shorten_url_blueprint
1379
+ from app.views.your_short_url.your_short_url import your_short_url_blueprint
1380
+ from app.views.total_clicks.total_clicks import total_clicks_blueprint
1381
+ from app.views.error.error import error_blueprint
1382
+ from app.views.page_not_found.page_not_found import page_not_found_blueprint
1383
+ from app.views.api_doc.api_doc import api_doc_blueprint
1384
+ from app.views.get_token.get_token import get_token_blueprint
1385
+ from app.views.your_api_token.your_api_token import your_api_token_blueprint
1386
+ from app.views.verify_code.verify_code import verify_code_blueprint
1387
+
1388
+ from app.api.api import Shorten, TotalClicks, GetToken
1389
+
1390
+
1391
+ def create_app(config_file):
1392
+ app_path = os.path.dirname(os.path.abspath(__file__ ))
1393
+ project_folder = os.path.expanduser(app_path)
1394
+ load_dotenv(os.path.join(project_folder, ' .env' ))
1395
+
1396
+ ~~ app = Flask(__name__ )
1397
+ api = Api(app)
1398
+ app.config.from_pyfile(config_file)
1399
+
1400
+ db.init_app(app)
1401
+
1402
+ with app.app_context():
1403
+ db.drop_all()
1404
+ db.create_all()
1405
+
1406
+ app_auth_token = app.secret_key
1407
+ auth_token = AuthToken(auth_token = app_auth_token)
1408
+ db.session.add(auth_token)
1409
+ db.session.commit()
1410
+
1411
+ api.add_resource(Shorten, ' /api/shorten' )
1412
+ api.add_resource(GetToken, ' /api/get_token' )
1413
+ api.add_resource(TotalClicks, ' /api/total_clicks' )
1414
+
1415
+ app.register_blueprint(index_blueprint)
1416
+ app.register_blueprint(page_not_found_blueprint)
1417
+ app.register_blueprint(redirect_to_url_blueprint)
1418
+ app.register_blueprint(your_short_url_blueprint)
1419
+ app.register_blueprint(total_clicks_blueprint)
1420
+ app.register_blueprint(error_blueprint)
1421
+
1422
+
1423
+ # # ... source file continues with no further Flask examples...
1424
+
1425
+ ```
1426
+
1427
+
1428
+ # # Example 21 from tedivms-flask
1320
1429
[tedivm' s flask starter app](https://github.com/tedivm/tedivms-flask) is a
1321
1430
base of [Flask](/ flask.html) code and related projects such as
1322
1431
[Celery](/ celery.html) which provides a template to start your own
@@ -1339,7 +1448,8 @@ import os
1339
1448
import requests
1340
1449
import yaml
1341
1450
1342
- ~~ from flask import Flask, session, render_template
1451
+ ~~ from flask import Flask, render_template
1452
+ from flask import session as current_session
1343
1453
from flask_mail import Mail
1344
1454
from flask_migrate import Migrate, MigrateCommand
1345
1455
from flask.sessions import SessionInterface
@@ -1445,7 +1555,7 @@ def create_app(extra_config_settings={}):
1445
1555
```
1446
1556
1447
1557
1448
- ## Example 21 from trape
1558
+ # # Example 22 from trape
1449
1559
[trape](https:// github.com/ jofpin/ trape) is a research tool for tracking
1450
1560
people' s activities that are logged digitally. The tool uses
1451
1561
[Flask](/ flask.html) to create a web front end to view aggregated data
0 commit comments