Skip to content
Snippets Groups Projects
Commit fd043890 authored by Julian's avatar Julian
Browse files

Limited invite validity period, extended token entropy, other small fixes

parent 9da3ac96
No related branches found
No related tags found
No related merge requests found
...@@ -69,6 +69,8 @@ ENABLE_PASSWORDRESET=True ...@@ -69,6 +69,8 @@ ENABLE_PASSWORDRESET=True
# Do not enable this on a public service! There is no spam protection implemented at the moment. # Do not enable this on a public service! There is no spam protection implemented at the moment.
SELF_SIGNUP=False SELF_SIGNUP=False
INVITE_MAX_VALID_DAYS=21
LOGINNAME_BLACKLIST=['^admin$', '^root$'] LOGINNAME_BLACKLIST=['^admin$', '^root$']
#MFA_ICON_URL = 'https://example.com/logo.png' #MFA_ICON_URL = 'https://example.com/logo.png'
......
...@@ -19,7 +19,7 @@ invite_roles = db.Table('invite_roles', ...@@ -19,7 +19,7 @@ invite_roles = db.Table('invite_roles',
class Invite(db.Model): class Invite(db.Model):
__tablename__ = 'invite' __tablename__ = 'invite'
id = Column(Integer(), primary_key=True, autoincrement=True) id = Column(Integer(), primary_key=True, autoincrement=True)
token = Column(String(128), unique=True, nullable=False, default=lambda: secrets.token_urlsafe(32)) token = Column(String(128), unique=True, nullable=False, default=lambda: secrets.token_urlsafe(48))
created = Column(DateTime, default=datetime.datetime.now, nullable=False) created = Column(DateTime, default=datetime.datetime.now, nullable=False)
creator_dn = Column(String(128), nullable=True) creator_dn = Column(String(128), nullable=True)
creator = DBRelationship('creator_dn', User) creator = DBRelationship('creator_dn', User)
......
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="valid-until">Expires After</label> <label for="valid-until">Valid Until</label>
<input class="form-control" type="datetime-local" id="valid-until" name="valid-until" value="{{ (datetime.now() + timedelta(hours=36)).replace(hour=23, minute=59, second=59, microsecond=0).isoformat(timespec='minutes') }}"> <input class="form-control" type="datetime-local" id="valid-until" name="valid-until" value="{{ (datetime.now() + timedelta(hours=36)).replace(hour=23, minute=59, second=59, microsecond=0).isoformat(timespec='minutes') }}">
<small class="text-muted">Must be within the next {{ config['INVITE_MAX_VALID_DAYS'] }} days</small>
</div> </div>
{% if allow_signup %} {% if allow_signup %}
<div class="form-group"> <div class="form-group">
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
{% else %} {% else %}
<input type="hidden" name="allow-signup" value="0"> <input type="hidden" name="allow-signup" value="0">
{% endif %} {% endif %}
{% if roles %}
<div class="form-group"> <div class="form-group">
<label for="valid-until">Granted Roles</label> <label for="valid-until">Granted Roles</label>
<table class="table table-sm"> <table class="table table-sm">
...@@ -46,12 +48,10 @@ ...@@ -46,12 +48,10 @@
<td>{{ role.description }}</td> <td>{{ role.description }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% if not roles %}
<tr><td colspan="3" class="bg-light text-muted text-center">There are no (non-base) roles yet</td></tr>
{% endif %}
</tbody> </tbody>
</table> </table>
</div> </div>
{% endif %}
<button type="submit" class="btn btn-primary"><i class="fa fa-save" aria-hidden="true"></i> Create Link</button> <button type="submit" class="btn btn-primary"><i class="fa fa-save" aria-hidden="true"></i> Create Link</button>
<a href="{{ url_for("invite.index") }}" class="btn btn-secondary">Cancel</a> <a href="{{ url_for("invite.index") }}" class="btn btn-secondary">Cancel</a>
</form> </form>
......
...@@ -76,10 +76,13 @@ def new_submit(): ...@@ -76,10 +76,13 @@ def new_submit():
invite = Invite(creator=user, invite = Invite(creator=user,
single_use=(request.values['single-use'] == '1'), single_use=(request.values['single-use'] == '1'),
valid_until=datetime.datetime.fromisoformat(request.values['valid-until']), valid_until=datetime.datetime.fromisoformat(request.values['valid-until']),
allow_signup=(request.values['allow-signup'] == '1')) allow_signup=(request.values.get('allow-signup', '0') == '1'))
for key, value in request.values.items(): for key, value in request.values.items():
if key.startswith('role-') and value == '1': if key.startswith('role-') and value == '1':
invite.roles.append(Role.query.get(key[5:])) invite.roles.append(Role.query.get(key[5:]))
if invite.valid_until > datetime.datetime.now() + datetime.timedelta(days=current_app.config['INVITE_MAX_VALID_DAYS']):
flash('The "Expires After" date is too far in the future')
return redirect(url_for('invite.new'))
if not invite.permitted: if not invite.permitted:
flash('You are not allowed to create invite links with these permissions') flash('You are not allowed to create invite links with these permissions')
return redirect(url_for('invite.new')) return redirect(url_for('invite.new'))
......
...@@ -28,7 +28,7 @@ class Signup(db.Model): ...@@ -28,7 +28,7 @@ class Signup(db.Model):
As long as they are not completed, signup requests have no effect each other As long as they are not completed, signup requests have no effect each other
or different parts of the application.''' or different parts of the application.'''
__tablename__ = 'signup' __tablename__ = 'signup'
token = Column(String(128), primary_key=True, default=lambda: secrets.token_urlsafe(32)) token = Column(String(128), primary_key=True, default=lambda: secrets.token_urlsafe(48))
created = Column(DateTime, default=datetime.datetime.now, nullable=False) created = Column(DateTime, default=datetime.datetime.now, nullable=False)
loginname = Column(Text) loginname = Column(Text)
displayname = Column(Text) displayname = Column(Text)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment