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

Moved token generation to common module and introduced token_urlfriendly


Broken mail clients like Thunderbird fail to recognize urlsafe characters
like "-" as part of an URL. token_urlfriendly avoids those characters.

Closes #93.

Co-authored-by: default avatarnd <nd@cccv.de>
parent e48585cb
No related branches found
No related tags found
1 merge request!60use token_hex instead of token_urlsafe to work around thunderbirds url handling
Pipeline #7380 passed
import secrets
import datetime
from flask import current_app
......@@ -9,6 +8,7 @@ from uffd.ldapalchemy.dbutils import DBRelationship
from uffd.database import db
from uffd.user.models import User
from uffd.signup.models import Signup
from uffd.utils import token_urlfriendly
invite_roles = db.Table('invite_roles',
Column('invite_id', Integer(), ForeignKey('invite.id'), primary_key=True),
......@@ -18,7 +18,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(48))
token = Column(String(128), unique=True, nullable=False, default=token_urlfriendly)
created = Column(DateTime, default=datetime.datetime.now, nullable=False)
creator_dn = Column(String(128), nullable=True)
creator = DBRelationship('creator_dn', User)
......
import datetime
import secrets
from sqlalchemy import Column, String, DateTime
from uffd.database import db
def random_token():
return secrets.token_hex(128)
from uffd.utils import token_urlfriendly
class Token():
token = Column(String(128), primary_key=True, default=random_token)
token = Column(String(128), primary_key=True, default=token_urlfriendly)
created = Column(DateTime, default=datetime.datetime.now)
class PasswordToken(Token, db.Model):
......
import datetime
import secrets
import math
import enum
from sqlalchemy import Column, String, Integer, DateTime, ForeignKey, Enum
......@@ -10,15 +9,7 @@ from sqlalchemy.ext.hybrid import hybrid_property
from uffd.ldapalchemy.dbutils import DBRelationship
from uffd.database import db
from uffd.user.models import User
def token_typeable(nbytes=None):
'''Return random text token that is easy to type (on mobile)'''
alphabet = '123456789abcdefghkmnopqrstuvwx' # No '0ijlyz'
if nbytes is None:
nbytes = secrets.DEFAULT_ENTROPY
nbytes_per_char = math.log(len(alphabet), 256)
nchars = math.ceil(nbytes / nbytes_per_char)
return ''.join([secrets.choice(alphabet) for _ in range(nchars)])
from uffd.utils import token_typeable
# Device login provides a convenient and secure way to log into SSO-enabled
# services on a secondary device without entering the user password or
......
import secrets
import datetime
from crypt import crypt
......@@ -8,6 +7,7 @@ from uffd.ldapalchemy.dbutils import DBRelationship
from uffd.database import db
from uffd.ldap import ldap
from uffd.user.models import User
from uffd.utils import token_urlfriendly
class Signup(db.Model):
'''Model that represents a self-signup request
......@@ -26,7 +26,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(48))
token = Column(String(128), primary_key=True, default=token_urlfriendly)
created = Column(DateTime, default=datetime.datetime.now, nullable=False)
loginname = Column(Text)
displayname = Column(Text)
......
import secrets
import math
def token_with_alphabet(alphabet, nbytes=None):
'''Return random text token that consists of characters from `alphabet`'''
if nbytes is None:
nbytes = max(secrets.DEFAULT_ENTROPY, 32)
nbytes_per_char = math.log(len(alphabet), 256)
nchars = math.ceil(nbytes / nbytes_per_char)
return ''.join([secrets.choice(alphabet) for _ in range(nchars)])
def token_typeable(nbytes=None):
'''Return random text token that is easy to type (on mobile)'''
alphabet = '123456789abcdefghkmnopqrstuvwx' # No '0ijlyz'
return token_with_alphabet(alphabet, nbytes=nbytes)
def token_urlfriendly(nbytes=None):
'''Return random text token that is urlsafe and works around common parsing bugs'''
alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return token_with_alphabet(alphabet, nbytes=nbytes)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment