diff --git a/uffd/default_config.cfg b/uffd/default_config.cfg index debf69ebf818a04d38bf32f29ac2ff57350b842b..559626029e02042fdaa36db1b6d22f937477363d 100644 --- a/uffd/default_config.cfg +++ b/uffd/default_config.cfg @@ -69,6 +69,8 @@ ENABLE_PASSWORDRESET=True # Do not enable this on a public service! There is no spam protection implemented at the moment. SELF_SIGNUP=False +INVITE_MAX_VALID_DAYS=21 + LOGINNAME_BLACKLIST=['^admin$', '^root$'] #MFA_ICON_URL = 'https://example.com/logo.png' diff --git a/uffd/invite/models.py b/uffd/invite/models.py index eb441fb92495ad0ef92d54fd5c622fb98b57988a..47826cd06f43944939df29780212656f7a73b2ed 100644 --- a/uffd/invite/models.py +++ b/uffd/invite/models.py @@ -19,7 +19,7 @@ invite_roles = db.Table('invite_roles', class Invite(db.Model): __tablename__ = 'invite' 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) creator_dn = Column(String(128), nullable=True) creator = DBRelationship('creator_dn', User) diff --git a/uffd/invite/templates/invite/new.html b/uffd/invite/templates/invite/new.html index d1f913acdf401b071dbb6abf031f649117b370ba..a27d50d6d00f2517700f298963fc653d3d82071f 100644 --- a/uffd/invite/templates/invite/new.html +++ b/uffd/invite/templates/invite/new.html @@ -10,8 +10,9 @@ </select> </div> <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') }}"> + <small class="text-muted">Must be within the next {{ config['INVITE_MAX_VALID_DAYS'] }} days</small> </div> {% if allow_signup %} <div class="form-group"> @@ -24,6 +25,7 @@ {% else %} <input type="hidden" name="allow-signup" value="0"> {% endif %} + {% if roles %} <div class="form-group"> <label for="valid-until">Granted Roles</label> <table class="table table-sm"> @@ -46,12 +48,10 @@ <td>{{ role.description }}</td> </tr> {% 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> </table> </div> + {% endif %} <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> </form> diff --git a/uffd/invite/views.py b/uffd/invite/views.py index d7a9eedc92d53c84cc69a0f4eeae9242af8faa98..bfe9af36ce6a697c26c782018f5967ff2bbcec73 100644 --- a/uffd/invite/views.py +++ b/uffd/invite/views.py @@ -76,10 +76,13 @@ def new_submit(): invite = Invite(creator=user, single_use=(request.values['single-use'] == '1'), 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(): if key.startswith('role-') and value == '1': 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: flash('You are not allowed to create invite links with these permissions') return redirect(url_for('invite.new')) diff --git a/uffd/signup/models.py b/uffd/signup/models.py index a2f4b72127ce32f3c2e99e30e6dd297c86cda4ab..2fabc8e587766a5f6f4e0f98ae83d410369cf2f1 100644 --- a/uffd/signup/models.py +++ b/uffd/signup/models.py @@ -28,7 +28,7 @@ class Signup(db.Model): As long as they are not completed, signup requests have no effect each other or different parts of the application.''' __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) loginname = Column(Text) displayname = Column(Text)