API & Client - refactor registration activation - #15

This commit is contained in:
Sam 2019-11-13 21:46:24 +01:00
parent 1398c7ff4a
commit 7ffcaad332
13 changed files with 45 additions and 128 deletions

View File

@ -144,8 +144,7 @@
<span class="nt">&quot;is_registration_enabled&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;max_single_file_size&quot;</span><span class="p">:</span> <span class="mi">1048576</span><span class="p">,</span>
<span class="nt">&quot;max_zip_file_size&quot;</span><span class="p">:</span> <span class="mi">10485760</span><span class="p">,</span>
<span class="nt">&quot;max_users&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="nt">&quot;registration&quot;</span><span class="p">:</span> <span class="kc">false</span>
<span class="nt">&quot;max_users&quot;</span><span class="p">:</span> <span class="mi">0</span>
<span class="p">},</span>
<span class="nt">&quot;status&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span>
<span class="p">}</span>
@ -181,8 +180,7 @@
<span class="nt">&quot;is_registration_enabled&quot;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nt">&quot;max_single_file_size&quot;</span><span class="p">:</span> <span class="mi">1048576</span><span class="p">,</span>
<span class="nt">&quot;max_zip_file_size&quot;</span><span class="p">:</span> <span class="mi">10485760</span><span class="p">,</span>
<span class="nt">&quot;max_users&quot;</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span>
<span class="nt">&quot;registration&quot;</span><span class="p">:</span> <span class="kc">true</span>
<span class="nt">&quot;max_users&quot;</span><span class="p">:</span> <span class="mi">10</span>
<span class="p">},</span>
<span class="nt">&quot;status&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span>
<span class="p">}</span>
@ -197,10 +195,10 @@
<dt class="field-even">Request JSON Object</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>gpx_limit_import</strong> (<em>integrer</em>) max number of files in zip archive</p></li>
<li><p><strong>is_registration_enabled</strong> (<em>boolean</em>) is registration enabled ?</p></li>
<li><p><strong>max_single_file_size</strong> (<em>integrer</em>) max size of a single file</p></li>
<li><p><strong>max_zip_file_size</strong> (<em>integrer</em>) max size of a zip archive</p></li>
<li><p><strong>max_users</strong> (<em>integrer</em>) max users allowed to register on instance</p></li>
<li><p><strong>registration</strong> (<em>boolean</em>) is registration enabled ?</p></li>
</ul>
</dd>
<dt class="field-odd">Request Headers</dt>

View File

@ -34,8 +34,7 @@ def get_application_config():
"is_registration_enabled": false,
"max_single_file_size": 1048576,
"max_zip_file_size": 10485760,
"max_users": 0,
"registration": false
"max_users": 0
},
"status": "success"
}
@ -85,8 +84,7 @@ def update_application_config(auth_user_id):
"is_registration_enabled": true,
"max_single_file_size": 1048576,
"max_zip_file_size": 10485760,
"max_users": 10,
"registration": true
"max_users": 10
},
"status": "success"
}
@ -94,10 +92,10 @@ def update_application_config(auth_user_id):
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:<json integrer gpx_limit_import: max number of files in zip archive
:<json boolean is_registration_enabled: is registration enabled ?
:<json integrer max_single_file_size: max size of a single file
:<json integrer max_zip_file_size: max size of a zip archive
:<json integrer max_users: max users allowed to register on instance
:<json boolean registration: is registration enabled ?
:reqheader Authorization: OAuth 2.0 Bearer Token
@ -127,8 +125,6 @@ def update_application_config(auth_user_id):
config.max_zip_file_size = config_data.get('max_zip_file_size')
if 'max_users' in config_data:
config.max_users = config_data.get('max_users')
if 'registration' in config_data:
config.registration = config_data.get('registration')
db.session.commit()
update_app_config_from_database(current_app, config)

View File

@ -6,7 +6,6 @@ from ..users.models import User
class AppConfig(db.Model):
__tablename__ = 'app_config'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
registration = db.Column(db.Boolean, default=False, nullable=False)
max_users = db.Column(db.Integer, default=0, nullable=False)
gpx_limit_import = db.Column(db.Integer, default=10, nullable=False)
max_single_file_size = db.Column(
@ -17,7 +16,7 @@ class AppConfig(db.Model):
@property
def is_registration_enabled(self):
nb_users = User.query.count()
return self.registration and nb_users < self.max_users
return self.max_users == 0 or nb_users < self.max_users
def serialize(self):
return {
@ -26,5 +25,4 @@ class AppConfig(db.Model):
"max_single_file_size": self.max_single_file_size,
"max_zip_file_size": self.max_zip_file_size,
"max_users": self.max_users,
"registration": self.registration,
}

View File

@ -1,6 +1,7 @@
import os
from fittrackee_api import db
from fittrackee_api.users.models import User
from .models import AppConfig
@ -15,14 +16,14 @@ def init_config():
(for FitTrackee versions prior to v0.3.0)
"""
existing_config = AppConfig.query.one_or_none()
nb_users = User.query.count()
if not existing_config:
config = AppConfig()
config.registration = (
False
config.max_users = (
nb_users
if os.getenv('REACT_APP_ALLOW_REGISTRATION') == "false"
else True
else 0
)
config.max_users = 0
config.max_single_file_size = os.environ.get(
'REACT_APP_MAX_SINGLE_FILE_SIZE', MAX_FILE_SIZE
)
@ -40,7 +41,6 @@ def update_app_config_from_database(current_app, db_config):
current_app.config['max_single_file_size'] = db_config.max_single_file_size
current_app.config['MAX_CONTENT_LENGTH'] = db_config.max_zip_file_size
current_app.config['max_users'] = db_config.max_users
current_app.config['registration'] = db_config.registration
current_app.config[
'is_registration_enabled'
] = db_config.is_registration_enabled

View File

@ -12,44 +12,25 @@ os.environ["FLASK_ENV"] = 'testing'
os.environ["APP_SETTINGS"] = 'fittrackee_api.config.TestingConfig'
def app_config_with_registration():
def get_app_config(with_config=False):
if with_config:
config = AppConfig()
config.gpx_limit_import = 10
config.max_single_file_size = 1 * 1024 * 1024
config.max_zip_file_size = 1 * 1024 * 1024 * 10
config.max_users = 10
config.registration = True
config.max_users = 100
db.session.add(config)
db.session.commit()
return config
def app_config_registration_disabled():
config = AppConfig()
config.gpx_limit_import = 20
config.max_single_file_size = 10485
config.max_zip_file_size = 104850
config.max_users = 0
config.registration = False
db.session.add(config)
db.session.commit()
return config
def get_app_config(app_type):
if app_type == 'with_registration':
return app_config_with_registration()
elif app_type == 'no_registration':
return app_config_registration_disabled()
else:
return None
def get_app(app_type=None):
def get_app(with_config=False):
app = create_app()
with app.app_context():
db.create_all()
app_db_config = get_app_config(app_type)
app_db_config = get_app_config(with_config)
if app_db_config:
update_app_config_from_database(app, app_db_config)
yield app
@ -64,17 +45,12 @@ def get_app(app_type=None):
@pytest.fixture
def app():
yield from get_app('with_registration')
yield from get_app(with_config=True)
@pytest.fixture
def app_no_config():
yield from get_app()
@pytest.fixture
def app_no_registration():
yield from get_app('no_registration')
yield from get_app(with_config=False)
@pytest.fixture()

View File

@ -24,8 +24,7 @@ def test_get_config(app, user_1):
assert data['data']['is_registration_enabled'] is True
assert data['data']['max_single_file_size'] == 1048576
assert data['data']['max_zip_file_size'] == 10485760
assert data['data']['max_users'] == 10
assert data['data']['registration'] is True
assert data['data']['max_users'] == 100
def test_get_config_no_config(app_no_config, user_1_admin):
@ -82,7 +81,7 @@ def test_update_config_as_admin(app, user_1_admin):
response = client.patch(
'/api/config',
content_type='application/json',
data=json.dumps(dict(registration=True, max_users=10)),
data=json.dumps(dict(gpx_limit_import=100, max_users=10)),
headers=dict(
Authorization='Bearer '
+ json.loads(resp_login.data.decode())['auth_token']
@ -92,12 +91,11 @@ def test_update_config_as_admin(app, user_1_admin):
assert response.status_code == 200
assert 'success' in data['status']
assert data['data']['gpx_limit_import'] == 10
assert data['data']['gpx_limit_import'] == 100
assert data['data']['is_registration_enabled'] is True
assert data['data']['max_single_file_size'] == 1048576
assert data['data']['max_zip_file_size'] == 10485760
assert data['data']['max_users'] == 10
assert data['data']['registration'] is True
def test_update_full_config_as_admin(app, user_1_admin):
@ -116,7 +114,6 @@ def test_update_full_config_as_admin(app, user_1_admin):
max_single_file_size=10000,
max_zip_file_size=25000,
max_users=50,
registration=True,
)
),
headers=dict(
@ -133,7 +130,6 @@ def test_update_full_config_as_admin(app, user_1_admin):
assert data['data']['max_single_file_size'] == 10000
assert data['data']['max_zip_file_size'] == 25000
assert data['data']['max_users'] == 50
assert data['data']['registration'] is True
def test_update_config_not_admin(app, user_1):
@ -146,7 +142,7 @@ def test_update_config_not_admin(app, user_1):
response = client.patch(
'/api/config',
content_type='application/json',
data=json.dumps(dict(registration=True, max_users=10)),
data=json.dumps(dict(gpx_limit_import=100, max_users=10)),
headers=dict(
Authorization='Bearer '
+ json.loads(resp_login.data.decode())['auth_token']
@ -193,7 +189,7 @@ def test_update_config_no_config(app_no_config, user_1_admin):
response = client.patch(
'/api/config',
content_type='application/json',
data=json.dumps(dict(registration=True, max_users=10)),
data=json.dumps(dict(gpx_limit_import=100, max_users=10)),
headers=dict(
Authorization='Bearer '
+ json.loads(resp_login.data.decode())['auth_token']

View File

@ -10,5 +10,4 @@ def test_application_config(app):
assert serialized_app_config['is_registration_enabled'] is True
assert serialized_app_config['max_single_file_size'] == 1048576
assert serialized_app_config['max_zip_file_size'] == 10485760
assert serialized_app_config['max_users'] == 10
assert serialized_app_config['registration'] is True
assert serialized_app_config['max_users'] == 100

View File

@ -259,28 +259,6 @@ def test_user_registration_invalid_data(app):
assert 'error' in data['status']
def test_user_registration_not_allowed(app_no_registration):
client = app_no_registration.test_client()
response = client.post(
'/api/auth/register',
data=json.dumps(
dict(
username='test',
email='test@test.com',
password='12345678',
password_conf='12345678',
)
),
content_type='application/json',
)
assert response.content_type == 'application/json'
assert response.status_code == 403
data = json.loads(response.data.decode())
assert data['status'] == 'error'
assert data['message'] == 'Error. Registration is disabled.'
def test_user_registration_max_users_exceeded(
app, user_1_admin, user_2, user_3
):

View File

@ -20,7 +20,6 @@ def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('app_config',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('registration', sa.Boolean(), nullable=False),
sa.Column('max_users', sa.Integer(), nullable=False),
sa.Column('gpx_limit_import', sa.Integer(), nullable=False),
sa.Column('max_single_file_size', sa.Integer(), nullable=False),

View File

@ -28,26 +28,17 @@ export default function Config({ appConfig, message, t, updateIsInEdition }) {
<tbody>
<tr>
<th scope="row">
{t('administration:Enable registration')}:
</th>
<td>
{appConfig.registration
? t('common:yes')
: t('common:no')}
</td>
</tr>
<tr>
<th scope="row">
{t('administration:Max. number of active users')}:
{t(
// eslint-disable-next-line max-len
'administration:Max. number of active users (if 0, no limitation)'
)}
:
</th>
<td>{appConfig.max_users}</td>
</tr>
<tr>
<th scope="row">
{t(
'administration:Max. size of ' + 'uploaded files'
)}
:
{t('administration:Max. size of uploaded files')}:
</th>
<td>{getFileSize(appConfig.max_single_file_size)}</td>
</tr>

View File

@ -73,28 +73,16 @@ class AdminApplication extends React.Component {
updateIsInEdition()
}}
>
<div className="form-group row">
<label
className="col-sm-6 col-form-label"
htmlFor="registration"
>
{t('administration:Enable registration')}:
</label>
<input
className="col-sm-5"
id="registration"
name="registration"
type="checkbox"
checked={formData.registration}
onChange={e => this.handleFormChange(e)}
/>
</div>
<div className="form-group row">
<label
className="col-sm-6 col-form-label"
htmlFor="max_users"
>
{t('administration:Max. number of active users')}:
{t(
// eslint-disable-next-line max-len
'administration:Max. number of active users (if 0, no limitation)'
)}
:
</label>
<input
className="col-sm-5"

View File

@ -8,12 +8,11 @@
"Back": "Back",
"Disable": "Disable",
"Enable": "Enable",
"Enable registration": "Enable registration",
"FitTrackee administration": "FitTrackee administration",
"id": "id",
"Image": "Image",
"Label": "Label",
"Max. number of active users": "Max. number of active users",
"Max. number of active users (if 0, no limitation)": "Max. number of active users",
"Max. files of zip archive": "Max. files of zip archive",
"Max. size of uploaded files": "Max. size of uploaded files",
"Max. size of uploaded files (in Mb)": "Max. size of uploaded files (in Mb)",

View File

@ -8,12 +8,11 @@
"Back": "Retour",
"Disable": "désactiver",
"Enable": "activer",
"Enable registration": "Activer les inscriptions",
"FitTrackee administration": "Administration de FitTrackee",
"id": "id",
"Image": "Image",
"Label": "Label",
"Max. number of active users": "Nombre maximum d'utilisateurs actifs",
"Max. number of active users (if 0, no limitation)": "Nombre maximum d'utilisateurs actifs",
"Max. files of zip archive": "Nombre max. de fichiers dans une archive zip",
"Max. size of uploaded files": "Taille max. des fichiers",
"Max. size of uploaded files (in Mb)": "Taille max. des fichiers (en Mo)",