def ResetPassword(request, token): restdata = {'data': '', 'regerror': '', 'token': token} registerobj = forms.Register() restdata['data'] = registerobj if request.method == 'POST': s = TimestampSigner(django_settings.SECRET_KEY) email = s.unsign(token) form = forms.ResetPassword(request.POST) if form.is_valid(): password1 = request.POST['password1'] password2 = request.POST['password2'] if form.pwd_validate(password1, password2): try: s = TimestampSigner(django_settings.SECRET_KEY) s.unsign(token, max_age=300) except: msg = {'msgerror': u'哎哟我去,连接已过期,请重发邮件!!'} return HttpResponse(json.dumps(msg)) users = Suser.objects.get(email=email) users.set_password(password1) users.save() msg = {'msginfo': u'恭喜您,密码修改成功!!!'} return HttpResponse(json.dumps(msg)) else: msg = {'msgerror': u'密码输入不一致!!'} return HttpResponse(msg) else: restdata['data'] = form else: return render(request, 'webapp/resetpass.html', restdata)
async def token_find(self, token: str) -> int: """Return a user ID from a token. Parses the token to get the user ID and then unsigns it using the user's hashed password as a secret key """ userid_encoded = token.split('.')[0] try: userid = int(base64.urlsafe_b64decode(userid_encoded)) except (binascii.Error, ValueError): return None raw_user = self.get_raw_user(userid) if raw_user is None: return s = TimestampSigner(raw_user['password']['hash']) try: s.unsign(token) except itsdangerous.BadSignature: return return userid
def test_general_api_security(self): ##TODO: Add General API security test """This Tests the API security that is checked before all POST and GET request""" get_return = self.app.get('/api/client_view', headers={ 'API_KEY': 'api_key', 'Client_ID': 'testuser' }) assert 'Failure": "Incorrect API Key' in get_return.data api_key = self.post_info() get_return = self.app.get('/api/client_view', headers={ 'API_KEY': api_key[0], 'Client_ID': 'fakeuser' }) assert 'Failure": "Invaild User' in get_return.data user = User.query.filter_by(Client_id="testuser2").first() get_return = self.app.get('/api/client_view', headers={ 'API_KEY': user.api_key, 'Client_ID': 'testuser2' }) assert 'Failure": "Incorrect IP for Client, Please Re-login in' in get_return.data signer = TimestampSigner(SECRET_KEY) time.sleep(1) try: signer.unsign(api_key, max_age=1) raise except: pass
class DefaultSigner: def __init__(self, secret, **kwargs): self.signer = TimestampSigner(secret, **kwargs) def unsign(self, secret, **kwargs): try: self.signer.unsign(secret, **kwargs) except (itsBadSignature, BadTimeSignature): raise BadSignature(f"Signature {secret} does not match")
class Auth: @classmethod def __init__(self, app): self.signer = TimestampSigner(app.config['SECRET_KEY']) self.app = app @classmethod def requires_login(self, f): @wraps(f) def decorated(*args, **kwargs): authentication_token = request.headers.get('Authentication-Token') if not authentication_token or not self.__is_token_valid( authentication_token): return response( status=401, message='Not authorized' ) return f(*args, **kwargs) return decorated @staticmethod def hash_password(password): return hashlib.sha256(password).hexdigest() @classmethod def generate_auth_token(self): token_random_string = ''.join( choice(ascii_letters) for i in range( self.app.config['TOKEN_RANDOM_STRING_LENGTH'])) return self.signer.sign(token_random_string) @classmethod def __is_token_valid(self, authentication_token): try: self.signer.unsign( authentication_token, max_age=self.app.config['TOKEN_VALIDITY_DURATION'] ) except SignatureExpired as e: self.app.logger.info('INFO: SignatureExpired, %s', str(e)) return False # valid token, but expired except BadSignature as e: self.app.logger.info('INFO: BadSignature, %s', str(e)) return False # invalid token return True
def signup(): if request.method == "POST": error = None token = request.form['token'] ts = TimestampSigner(current_app.secret_key) try: username = ts.unsign(token, 60*5).decode("utf-8") # 2 minutes except SignatureExpired: error = "Token has expired" except BadSignature: error = "Invalid token" else: db = get_db() users = db.table("users") if users.contains(Query().username == username): error = "That user already exists" else: users.insert({"username":username,"role":0,"password":generate_password_hash(request.form['password'])}) if error is None: session.clear() flash("Successfully created user! You can now login.", "success") return redirect(url_for("auth.login")) else: flash(error, "error") return render_template("auth/signup.html")
def verifyCdata(cdata, secretkey, mxtime): s = TimestampSigner(secretkey) try: string = s.unsign(cdata, max_age=mxtime) return string except: return False
def get(self): args = get_parser('activation').parse_args() serial = args['serial'] change_email = redis.get('change_email:{}'.format(serial)) if not change_email: return make_response(redirect('/#!/?error=激活码无效')) change_email = change_email.decode() signer = TimestampSigner( current_app.config['SECRET_KEY'], salt='change_email') try: username = signer.unsign( base64.b64decode(serial.encode('utf-8')), max_age=172800).decode('utf-8') user = User.query.filter_by(username=username).first() if not user: return make_response(redirect('/#!/?error=激活码无效')) authentication = db_session.query(Authentication).filter( AuthenticationType.logic == 'email', Authentication.type_id == AuthenticationType.id, Authentication.user_id == user.id).first() authentication.accept() authentication.fields[0].value = change_email user.email = change_email redis.delete('change_email:{}'.format(serial)) db_session.commit() except (itsdangerous.BadSignature, itsdangerous.SignatureExpired): abort(400, message='激活码无效') else: return make_response(redirect('/#!/?success=修改邮箱成功'))
def parse_auth(): """Parse the authentication token attached to the request. This function tries to retrieve the authentication token attached to the request by. It first looks for `X-Auth-Token` in the request headers. If no such header could be found, it checks for `Auth-Token` in the request cookies. The function returns the owner UID associated with the token attached to the request, or raises an exception if none of these locations contains a valid one. :raises ~trexmo.core.exc.InvalidTokenError: if the given token is missing or invalid. :raises ~trexmo.core.exc.ExpiredTokenError: if the given token expired. """ auth_token = request.headers.get('X-Auth-Token', request.cookies.get('Auth-Token')) if auth_token is None: raise InvalidTokenError() signer = TimestampSigner(current_app.secret_key) try: auth = signer.unsign(auth_token, max_age=current_app.config['AUTH_TOKEN_DURATION']) except BadSignature: raise InvalidTokenError() except SignatureExpired: raise ExpiredTokenError() return auth.decode()
def email_check(): """ 校验邮箱有效性 http://localhost:5000/email/[email protected] """ sign = request.args.get('sign', '') from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature s = TimestampSigner(app.config['SECRET_KEY']) try: # email = s.unsign(sign, max_age=5) # 5秒过期 email = s.unsign(sign, max_age=30*24*60*60) # 1个月过期 # return email # 校验通过,更新邮箱验证状态 from user_auth import update_user_auth_rows result = update_user_auth_rows({'verified': 1}, **{'auth_type': 'email', 'auth_key': email}) if result == 1: flash(u'%s, Your mailbox has been verified' % email, 'success') return redirect(url_for('login')) else: flash(u'%s, Sorry, Your mailbox validation failed' % email, 'warning') except SignatureExpired as e: # 处理签名超时 flash(e.message, 'warning') except BadTimeSignature as e: # 处理签名错误 flash(e.message, 'warning') return redirect(url_for('reg'))
def update_user_password(): email = request.form.get('email') if not email: return 'Bad Request', 404 signed_data = request.headers['Authorisation'] client_key = app.config['WWW_CLIENT_KEY'] signer = TimestampSigner(client_key, digest_method=hashlib.sha256) try: unsigned = signer.unsign(signed_data, max_age=5) client_id, user_email, password = unsigned.decode('utf-8').split(':') if client_id != app.config['WWW_CLIENT_ID']: raise Exception if email != user_email: raise Exception user = AuthUser.objects.filter(email=email).first() if not user: abort(404) else: user.set_password(password) user.save() return 'OK', 200 except Exception as ex: log_traceback(current_app.logger, ex) return 'Unauthorized', 401
class CookieBackend(SessionBackend): """Stores session data in the browser's cookie as a signed string.""" def __init__(self, secret_key: t.Union[str, Secret], max_age: int): self._signer = TimestampSigner(str(secret_key)) self._max_age = max_age async def read(self, session_id: str) -> t.Dict: """A session_id is a signed session value.""" try: data = self._signer.unsign(session_id, max_age=self._max_age) return json.loads(b64decode(data).decode()) except (BadSignature, SignatureExpired): return {} async def write(self, data: t.Dict, session_id: t.Optional[str] = None) -> str: """The data is a session id in this backend.""" encoded_data = b64encode(json.dumps(data).encode("utf-8")) return self._signer.sign(encoded_data).decode("utf-8") async def remove(self, session_id: str) -> None: """Session data stored on client side - no way to remove it.""" async def exists(self, session_id: str) -> bool: return False
def reset(): pass_secret = current_app.config.get('PASS_SECRET_KEY') pass_token_age = current_app.config.get('PASS_TOKEN_AGE') test_mode = current_app.config.get('TESTING') token = request.json.get('token') old_password = request.json.get('old_password') new_password = request.json.get('new_password') singer = TimestampSigner(pass_secret) try: email_bytes = singer.unsign(token.encode(), max_age=pass_token_age) email = email_bytes.decode('utf-8') user = User.get_by_email(email) if user and user.password_match(old_password): user.update(password=new_password) return make_response(jsonify({'message': 'Password resetted!'}), HTTPStatus.CREATED) return make_response(jsonify({'message': { 'email': 'Not found' }}), HTTPStatus.NOT_FOUND) except SignatureExpired: return make_response(jsonify({'message': { 'token': 'Expired' }}), HTTPStatus.FORBIDDEN) except: return make_response(jsonify({'message': { 'token': 'Invalid value' }}), HTTPStatus.BAD_REQUEST)
def itsDecode(data: str, time: int = 15, url_safe_key: str = DEFAULT_SAFE_KEY, time_safe_key: str = DEFAULT_SAFE_KEY) -> (bool, str): ''' @description: its解密 @param {data} data 加密数据 @param {int} time 过期时间 @param {str} url_safe_key URL加密密钥 @param {str} time_safe_key Time加密密钥 @return: True/False, Data ''' result = None time = int(time) try: tSafe = TimestampSigner(time_safe_key) tUnsign = tSafe.unsign(data, time) except: return False, "授权过期" try: uSafe = URLSafeSerializer(url_safe_key) result = uSafe.loads(url_safe_key) return True, result except: return False, "解析失败"
def email_check(): """ 校验邮箱有效性 http://localhost:5000/email/[email protected] """ sign = request.args.get('sign', '') from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature s = TimestampSigner(app.config['SECRET_KEY']) try: # email = s.unsign(sign, max_age=5) # 5秒过期 email = s.unsign(sign, max_age=30*24*60*60) # 1个月过期 # return email # 校验通过,更新邮箱验证状态 from user_auth import update_user_auth_rows result = update_user_auth_rows({'verified': 1}, **{'auth_type': 'email', 'auth_key': email}) if result == 1: flash(u'%s, Your mailbox has been verified' % email, 'success') return redirect(url_for('login')) else: flash(u'%s, Sorry, Your mailbox validation failed' % email, 'warning') except SignatureExpired as e: # 处理签名超时 flash(e.message, 'warning') except BadTimeSignature as e: # 处理签名错误 flash(e.message, 'warning') return redirect(url_for('reg.index'))
def reset_user_password_step_two(form): """ second step of the password reset: check that the hash matches the temp password, force the change on ads classic """ #create an itsdangerous object to sign the verification email and encrypt the password itsd = TimestampSigner(config.ACCOUNT_VERIFICATION_SECRET) reset_code = form.resetcode.data try: code = itsd.unsign(reset_code, max_age=10800) #code valid only 3 hours except BadTimeSignature: app.logger.error('User password reset error: used reset code not valid. Email used: %s ; reset code: %s' % (form.login.data, reset_code)) return False, 'The reset code is not valid.', 'error' except SignatureExpired: app.logger.error('User password reset error: used reset code expired. Email used: %s ; reset code: %s' % (form.login.data, reset_code)) return False, 'The reset code has expired. Please request a new one.', 'error' #check if the reset code is the same stored in the DB loc_db_user = AdsUserRecord.query.filter(AdsUserRecord.username==form.login.data) #@UndefinedVariable #get the user object user_rec = loc_db_user.first() if reset_code != user_rec.password: app.logger.error('User password reset error: used valid reset code but it doesn\'t match the one in the DB. Email used: %s ; reset code: %s' % (form.login.data, reset_code)) return False, 'The reset code is not valid.', 'error' else: #proceed with the actual reset classic_user = reset_classic_password(form.login.data, form.new_password.data) if classic_user and classic_user.get('message') == 'ACCOUNT_UPDATED': #remove the reset code from the password field of the local db loc_db_user.set(password='').execute() return True, 'Password successfully updated.', 'success' else: app.logger.error('ADS Classic account modification error: return message not expected. Tried to force update password: login %s' % form.login.data) return False, 'Problems in the account modification. Please try again.', 'error'
def email_check(): """ 校验邮箱有效性 http://localhost:5000/email/[email protected] """ sign = request.args.get('sign', '') from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature from app_frontend import app s = TimestampSigner(app.config['SECRET_KEY']) try: # email = s.unsign(sign, max_age=5) # 5秒过期 email = s.unsign(sign, max_age=30 * 24 * 60 * 60) # 1个月过期 # return email # 校验通过,更新邮箱验证状态 from app_frontend.api.user_auth import update_user_auth_rows result = update_user_auth_rows({'verified': 1}, **{ 'type_auth': TYPE_AUTH_EMAIL, 'auth_key': email }) if result == 1: flash(u'%s, 邮箱成功激活' % email, 'success') return redirect(url_for('auth.index')) else: flash(u'%s, 邮箱激活失败' % email, 'warning') except SignatureExpired as e: # 处理签名超时 flash(e.message, 'warning') except BadTimeSignature as e: # 处理签名错误 flash(e.message, 'warning') return redirect(url_for('reg.index'))
async def read_item(request: Request, id: str): # TODO: check that the file exist, if yes .. s = TimestampSigner('secret-key') try: filename = s.unsign(id, max_age=50).decode() return templates.TemplateResponse("download.html", { "request": request, "id": filename }) except SignatureExpired: try: # check if is a file # Path(os.environ['DOWNLOAD_DIR'], str(id.rsplit('.', 2)[0]) os.remove( Path(os.environ['DOWNLOAD_DIR'], str(id.rsplit('.', 2)[0]))) except OSError: pass return templates.TemplateResponse("expired.html", { "request": request, "id": id }) except BadSignature: return templates.TemplateResponse("error.html", { "request": request, "id": id })
def register_user(): data = request.form if not (data['full_name'] or data['email']): return 'Bad Request', 404 signed_data = request.headers['Authorisation'] client_key = app.config['WWW_CLIENT_KEY'] signer = TimestampSigner(client_key, digest_method=hashlib.sha256) try: unsigned = signer.unsign(signed_data, max_age=5) client_id, email, full_name = unsigned.decode('utf-8').split(':') if client_id != app.config['WWW_CLIENT_ID']: raise Exception if email != data['email']: raise Exception if full_name != data['full_name']: raise Exception except Exception as ex: log_traceback(current_app.logger, ex) return 'Unauthorized', 401 person = registers.Person() person.born_at = datetime.fromtimestamp(mktime(gmtime(0))) person.full_name = full_name person.save() random_temp_password = uuid4().hex user = auth.AuthUser.create_user(email, random_temp_password) user.person_uri = person.uri user.save() return 'Created', 201
def confirm_validate_token(self, token, expiration=3600): serializer = utsr(self.security_key) timeStamp = TimestampSigner(self.security_key) username = serializer.loads(token, salt=self.salt) username = timeStamp.unsign(username, max_age=expiration) print(username) return username
class Tokenizer(object): """ A class for creating cryptographically signed tokens used by CivID. >>> tokenizer = Tokenizer('123') >>> lt = tokenizer.create_login_token('gatzy') >>> tokenizer.validate_login_token(lt) 'gatzy' >>> ic = tokenizer.create_identity_code('ttk2') >>> tokenizer.validate_identity_code(ic) 'ttk2' """ def __init__(self, signing_key): self.key = signing_key self.signer = TimestampSigner(signing_key) def short_sig(self, string): """ Returns a token computed from truncating the hash of the given string with the signing key. """ return base64.urlsafe_b64encode( hashlib.sha256(self.key + string).digest() )[:SHORT_SIG_LENGTH] def create_login_token(self, username): """ Creates a login token of the form "signatureUsername". This token is bound to a UNIX timestamp divided by LOGIN_WINDOW_S, but it is not stored within the token in order to limit its length. """ return self.short_sig(username + now_str()) + username def validate_login_token(self, token): if len(token) < SHORT_SIG_LENGTH + MIN_USERNAME_LENGTH: raise InvalidTokenError("Malformed token") signature = token[0:SHORT_SIG_LENGTH] user = token[SHORT_SIG_LENGTH:] if ( signature != self.short_sig(user + now_str()) and signature != self.short_sig(user + last_period_str()) ): raise InvalidTokenError("Login link invalid or expired") return user def create_identity_code(self, username): # Identity codes contain this silly "scrambled" version of the username # to discourage naive implementations from parsing it out of the code # without making a request to validate it against the CivID server. return self.signer.sign(scramble_username(username)) def validate_identity_code(self, code): try: return unscramble_username(self.signer.unsign(code, max_age=CODE_WINDOW_S)) except: raise InvalidCodeError()
def generate_reset_token(): s = TimestampSigner( "Secret") # Creating a timestamp signer with an associated secret key string = s.sign("foo") # Attaches time information of the signing print(s.unsign( string, max_age=20)) # Decrypts the received string with the timestamp signer return string
def logout(): body = request.get_json() if body['token'] is None: return 'token field is required', 400 token = body['token'].encode('utf8') signer = TimestampSigner(secret) try: signer.unsign(token, max_age=5 * 60) invalidated_token = InvalidatedToken(token) db.session.add(invalidated_token) db.session.commit() return '', 200 except: return 'Provided token is invalid or already expired', 400
class TokenManager(object): def setup(self, secret): """ Create a cypher to encrypt IDs and a signer to sign tokens.""" # Create cypher to encrypt IDs key = secret + '0123456789abcdef' # ensure >=16 characters sixteen_byte_key = key[0:16] # get first 16 characters self.cipher = AES.new(sixteen_byte_key) # Create signer to sign tokens self.signer = TimestampSigner(secret) def encrypt_id(self, id): """ Encrypts integer ID to url-safe base64 string.""" str1 = '%016d' % id # --> 16 byte integer string str2 = self.cipher.encrypt(str1) # --> encrypted data str3 = base64.urlsafe_b64encode(str2) # --> URL safe base64 string with '==' return str3[0:-2] # --> base64 string without '==' def decrypt_id(self, encrypted_id): """ Decrypts url-safe base64 string to integer ID""" # In Python3, encrypted_id is <type 'str'> and needs to be converted to bytes if type(encrypted_id)=='str': # pragma: no cover encrypted_id = encrypted_id.encode('ascii') try: str3 = encrypted_id + b'==' # --> base64 string with '==' str2 = base64.urlsafe_b64decode(str3) # --> encrypted data str1 = self.cipher.decrypt(str2) # --> 16 byte integer string return int(str1) # --> integer id except Exception as e: # pragma: no cover print('!!!Exception in decrypt_id!!!') return 0 def generate_token(self, id): """ Return token with id, timestamp and signature""" # In Python3 we must make sure that bytes are converted to strings. # Hence the addition of '.decode()' return self.signer.sign(self.encrypt_id(id)).decode() def verify_token(self, token, expiration_in_seconds): """ Verify token and return (is_valid, has_expired, id). Returns (True, False, id) on success. Returns (False, True, None) on expired tokens. Returns (False, False, None) on invalid tokens.""" try: data = self.signer.unsign(token, max_age=expiration_in_seconds) is_valid = True has_expired = False id = self.decrypt_id(data) except SignatureExpired: is_valid = False has_expired = True id = None except BadSignature: is_valid = False has_expired = False id = None return (is_valid, has_expired, id)
async def raw_token_check(token, db=None): db = db or app.db # just try by fragments instead of # unpacking fragments = token.split('.') user_id = fragments[0] try: user_id = base64.b64decode(user_id.encode()) user_id = int(user_id) except (ValueError, binascii.Error): raise Unauthorized('Invalid user ID type') pwd_hash = await db.fetchval( """ SELECT password_hash FROM users WHERE id = $1 """, user_id) if not pwd_hash: raise Unauthorized('User ID not found') signer = TimestampSigner(pwd_hash) try: signer.unsign(token) log.debug('login for uid {} successful', user_id) # update the user's last_session field # so that we can keep an exact track of activity, # even on long-lived single sessions (that can happen # with people leaving their clients open forever) await db.execute( """ UPDATE users SET last_session = (now() at time zone 'utc') WHERE id = $1 """, user_id) return user_id except BadSignature: log.warning('token failed for uid {}', user_id) raise Forbidden('Invalid token')
class Tokenizer(object): """ A class for creating cryptographically signed tokens used by CivID. >>> tokenizer = Tokenizer('123') >>> lt = tokenizer.create_login_token('gatzy') >>> tokenizer.validate_login_token(lt) 'gatzy' >>> ic = tokenizer.create_identity_code('ttk2') >>> tokenizer.validate_identity_code(ic) 'ttk2' """ def __init__(self, signing_key): self.key = signing_key self.signer = TimestampSigner(signing_key) def short_sig(self, string): """ Returns a token computed from truncating the hash of the given string with the signing key. """ return base64.urlsafe_b64encode( hashlib.sha256(self.key + string).digest())[:SHORT_SIG_LENGTH] def create_login_token(self, username): """ Creates a login token of the form "signatureUsername". This token is bound to a UNIX timestamp divided by LOGIN_WINDOW_S, but it is not stored within the token in order to limit its length. """ return self.short_sig(username + now_str()) + username def validate_login_token(self, token): if len(token) < SHORT_SIG_LENGTH + MIN_USERNAME_LENGTH: raise InvalidTokenError("Malformed token") signature = token[0:SHORT_SIG_LENGTH] user = token[SHORT_SIG_LENGTH:] if (signature != self.short_sig(user + now_str()) and signature != self.short_sig(user + last_period_str())): raise InvalidTokenError("Login link invalid or expired") return user def create_identity_code(self, username): # Identity codes contain this silly "scrambled" version of the username # to discourage naive implementations from parsing it out of the code # without making a request to validate it against the CivID server. return self.signer.sign(scramble_username(username)) def validate_identity_code(self, code): try: return unscramble_username( self.signer.unsign(code, max_age=CODE_WINDOW_S)) except: raise InvalidCodeError()
def wrapper(*args, **kwargs): headers = request.headers if 'token' not in headers: return '', 403 token = headers['token'].encode('utf8') signer = TimestampSigner(secret) try: signer.unsign(token, max_age=5 * 60) invalidated_token = InvalidatedToken.query.filter_by( token=token).first() if invalidated_token is None: return f(*args, **kwargs) else: return '', 403 except: return '', 403
def get_username_from_recovery_token(app, recovery_token): signer = TimestampSigner(app.config['SECRET_KEY'], salt='recovery') try: username = signer.unsign(recovery_token, max_age=timedelta(hours=1).seconds) except (BadSignature, SignatureExpired) as e: return None return username
class SignedCookieManager: session = Session def __init__(self, secret, store, cookie='sid'): self.store = store self.delta = store.delta # lifespan delta in seconds. self.cookie_name = cookie self.signer = TimestampSigner(secret) def generate_id(self): return str(uuid4()) def refresh_id(self, sid): return str(self.signer.sign(sid), 'utf-8') def verify_id(self, ssid): return self.signer.unsign(ssid, max_age=self.delta) def get_session(self, cookie): new, sid = self.get_id(cookie) return self.session(sid, self.store, new=new) def get_id(self, cookie): if cookie is not None: morsels = parse(cookie) signed_sid = morsels.get(self.cookie_name) if signed_sid is not None: try: sid = self.verify_id(signed_sid) return False, str(sid, 'utf-8') except itsdangerous.exc.SignatureExpired: # Session expired. We generate a new one. pass return True, self.generate_id() def cookie(self, sid, path="/", domain="localhost"): """We enforce the expiration. """ # Refresh the signature on the sid. ssid = self.refresh_id(sid) # Generate the expiration date using the delta expires = datetime.now() + timedelta(seconds=self.delta) # Create the cookie containing the ssid. cookie = Cookie( name=self.cookie_name, value=ssid, path=path, domain=domain, expires=expires) value = str(cookie) # Check value if len(value) > 4093: # 4096 - 3 bytes of overhead raise ValueError('The Cookie is over 4093 bytes.') return value
def _check_token(token): from itsdangerous import TimestampSigner, SignatureExpired signer = TimestampSigner(app.config['SECRET_KEY']) try: email = signer.unsign(token, max_age=app.config['TOKEN_MAX_AGE_SECONDS']) return email except SignatureExpired as e: current_app.logger.info('token expired %s' % e) return None
def __init__(self, request): self.__acl__ = [] config = request.registry.settings req_url_secret = request.params.get("secret") req_secret = request.headers.get("x-channelstream-secret", req_url_secret) addr = request.environ["REMOTE_ADDR"] if not is_allowed_ip(addr, config): log.warning("IP: {} is not whitelisted".format(addr)) return if req_secret: max_age = 60 if config["validate_requests"] else None signer = TimestampSigner(config["secret"]) signer.unsign(req_secret, max_age=max_age) else: return self.__acl__ = [(Allow, Everyone, ALL_PERMISSIONS)]
def __init__(self, request): self.__acl__ = [] config = request.registry.settings req_url_secret = request.params.get("secret") req_secret = request.headers.get("x-channelstream-secret", req_url_secret) addr = request.environ["REMOTE_ADDR"] if not is_allowed_ip(addr, config): log.warning("IP: {} is not whitelisted".format(addr)) return if req_secret: signer = TimestampSigner(config["secret"]) signer.unsign(req_secret, max_age=60) else: return self.__acl__ = [(Allow, Everyone, ALL_PERMISSIONS)]
def load_user_from_request(request): authorization = request.headers.get('Authorization') if authorization is None or not authorization.startswith('Bearer '): return None token = authorization.split(' ', 1)[-1] signer = TimestampSigner(app.secret_key) id = signer.unsign(token) user = User.query.get(int(id)) return user
def before_request(self,*args): """Verfies that the API is Vaild for the correct user and the IP address hasn't changed since log in""" signer = TimestampSigner(SECRET_KEY) api_key = request.headers['API_KEY'] Client_id = request.headers['Client_ID'] ip_address = request.remote_addr user = User.query.filter_by(Client_id=Client_id).first() if user == None: return make_response(jsonify({'Failure': 'Invaild User'}), 400) if api_key != user.api_key: return make_response(jsonify({'Failure': 'Incorrect API Key'}), 400) if ip_address != user.current_login_ip: return make_response(jsonify({'Failure': 'Incorrect IP for Client, Please Re-login in'}), 400) try: signer.unsign(api_key, max_age=86164) except: return make_response(jsonify({'Failure': 'Invaild API Key, please request new API Key'}), 400)
def get_api_key(request): try: api_key_name = request.POST.get('api_key', '') except AttributeError: api_key_name = request.form.get('api_key', '') # There is probably a better way to do this. api_keys = ApiKey.all() api_key = None for ak in api_keys: if api_key_name.startswith(ak.name): try: s = TimestampSigner(ak.key) s.unsign(api_key_name, max_age=120) api_key = ak except SignatureExpired: pass return api_key
def decrypt(string, max_age=15000): """ This method will return decrypted version of an encrypted string. If age of encryption is greater than max age it will return False """ try: signer = TimestampSigner(encrypt_key) return signer.unsign(string, max_age=max_age) except: return False
def decode_agent_websocket_token(token): signer = TimestampSigner(app.config['SECRET_KEY'], salt="websocket_agent") try: agent_id = signer.unsign(token, max_age=60) except BadData as e: raise ValueError("Invalid Token") agent = Agent.query.get(agent_id) if agent is None: raise ValueError("No agent found with that ID") return agent
def check_token(token, app): signer = TimestampSigner(app.config["SECRET_KEY"]) try: email = signer.unsign(token, max_age=app.config["TOKEN_MAX_AGE_SECONDS"]) if isinstance(email, bytes): email = email.decode("utf-8") return email except SignatureExpired as e: current_app.logger.info("token expired %s" % e) return None
def verify_auth_token(token): s = TimestampSigner(current_app.config['SECRET_KEY']) try: id = s.unsign(token, max_age=3600) except SignatureExpired: return None # valid token, but expired except BadSignature: return None # invalid token user = User.query.get(id) return user
def validate_reset_token(reset_user, token): s = TimestampSigner(app.config.get('SECRET_KEY')) try: new_token = s.unsign(token, max_age=43200) redis_val = app.redis_db.get("password-reset:#"+str(reset_user)) if (token == redis_val.decode("utf8")): return True else: return False except Exception as e: return False
def validate_reset_token(reset_user, token): s = TimestampSigner(app.config.get('SECRET_KEY')) try: new_token = s.unsign(token, max_age=43200) redis_val = app.redis_db.get("password-reset:#" + str(reset_user)) if (token == redis_val.decode("utf8")): return True else: return False except Exception as e: return False
def Activate(request, token): s = TimestampSigner(django_settings.SECRET_KEY) email = s.unsign(token) try: s = TimestampSigner(django_settings.SECRET_KEY) s.unsign(token, max_age=300) except: users = Suser.objects.filter(email=email) for user in users: user.delete() return HttpResponse('连接已过期!!') try: user = Suser.objects.get(email=email) except Suser.DoesNotExist: return HttpResponse('用户不存在!!') user.is_active = True user.save() return HttpResponseRedirect('/')
def verify_session_token(token): timer = TimestampSigner(app.config["SECRET_KEY"]) serial = Serializer(app.config["SECRET_KEY"]) global user_dict exp = GAV.time_out_req try: sess_token = timer.unsign(token, max_age=exp) userid = serial.loads(sess_token)["userId"] except Exception as e: raise SignatureExpired("Entered signature Expired") return Employee.query.get(userid)
def get_auth_user(self): """ Use self-signed TimestampSigner to retrieve auth_id """ auth_token = parse_cookie(self.ws.environ['HTTP_COOKIE']).get('auth_token') if auth_token is None: self.on_close('invalid authentication') self.ws.send('AUTH') # tell client to reauth self.ws.close() else: expiration_seconds = app.config['AUTH_TOKEN_SECONDS'] signer = TimestampSigner(app.config['SECRET_KEY']) try: auth_id = signer.unsign(auth_token, max_age=expiration_seconds) # Validate user is in db user = models.User.query.filter_by(auth_id=auth_id).first() if user is None: self.ws.send('AUTH') self.ws.close() return # Upgrade token if token is about to expire try: reissue_seconds = app.config['REISSUE_AUTH_TOKEN_SECONDS'] auth_id = signer.unsign(auth_token, max_age=reissue_seconds) except SignatureExpired: signer = TimestampSigner(app.config['SECRET_KEY']) auth_token = signer.sign(auth_id) self.ws.send('UPGRADE:{}'.format(auth_token)) return user except SignatureExpired: self.on_close('auth token expired') self.ws.send('AUTH') # tell client to reauth self.ws.close() except BadSignature: self.on_close('invalid authentication') self.ws.send('AUTH') # tell client to reauth self.ws.close()
def get_operator_id(operator_cn): CONF = get_config() signer = TimestampSigner(CONF.SECRET) try: cookie = operator_cn.get_cookie(CONF.OPERATOR_ID_COOKIE) if cookie is None: raise Exception('Cookie not found') operator_id = signer.unsign(cookie, max_age=CONF.AUTH_EXPIRY) return operator_id except Exception as e: logging.error('Login error: %s.', e) return False
def dispatch(self, *args, **kwargs): if "em_tk" not in self.request.GET: return HttpResponseRedirect(reverse('home')) email_token = self.request.GET.get('em_tk') s = TimestampSigner(SECRET_KEY,salt="change-password") try: self.email_address = s.unsign(email_token, max_age=MAX_TOKEN_AGE) except:# itsdangerous.BadSignature: raise Http404 #return HttpResponseRedirect(reverse('home')) return super(PasswordChangeView, self).dispatch(*args, **kwargs)
def authorize_password_reset(userid, email): s = TimestampSigner(app.secret_key) user_email = s.unsign(email) conn, cursor = hvb_connect_db(app.hvb_conf["db"]) cursor.execute("""select id, compendium from users where email = %s; """, [user_email]) user = cursor.fetchall() if len(user) == 0: print("hvb.password_reset: email not known") return abort(400) elif len(user) > 1: print("hvb.login: ERROR: email associated with multiple accounts") hvb_close_db(conn, cursor) id = user[0][0] compendium = user[0][1] session["email"] = user_email if str(id) + str(compendium) == str(s.unsign(userid)): return render_template("password-reset.html", email=user_email) else: abort(400)
def authorize(request): auth_header = request.headers.get('Authorization') if auth_header: try: auth_token = auth_header.split(" ")[1] except IndexError: responseObject = { 'status': 'fail', 'message': 'Bearer token malformed.', 'status_int': 401 } return make_response(jsonify(responseObject), 401) else: auth_token = '' if auth_token: resp = User.decode_auth_token(auth_token) if not isinstance(resp, str): s = TimestampSigner(app.config.get('SECRET_KEY')) try: csrf_token = s.unsign(request.headers.get('CSRF-Token')) except Exception as e: responseObject = { 'status': 'fail', 'message': 'Invalid data.', 'status_int': 401 } return make_response(jsonify(responseObject), 401) user = User.query.filter_by(id=resp).first() responseObject = { 'status': 'success', 'data': { 'user_id': user.id, 'email': user.email, 'admin': user.admin, 'registered_on': user.registered_on } } return make_response(jsonify(responseObject), 201) responseObject = { 'status': 'fail', 'message': resp, 'status_int': 401 } return make_response(jsonify(responseObject), 401) else: responseObject = { 'status': 'fail', 'message': 'Provide a valid auth token.', 'status_int': 401 } return make_response(jsonify(responseObject), 401)
def reset_password_from_token(reset_token, new_password): s = TimestampSigner(os.getenv("SECRET_KEY"), salt="reset-password") try: email = s.unsign(reset_token, max_age=60*60*24).lower() # 24 hours except SignatureExpired: raise PasswordResetError("expired-token") except (BadTimeSignature, BadSignature): raise PasswordResetError("invalid-token") user = get_profile_from_id(email, "email", include_products=False) user.set_password(new_password) return user
def check_token(self, token_sign): """ 校验 token, 返回解密后的 token """ from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature s = TimestampSigner(self._sign_key) try: token = s.unsign(token_sign, max_age=60) # 60秒过期 return {'success': token} except SignatureExpired as e: # 处理签名超时 return {'error': e.message} except BadTimeSignature as e: # 处理签名错误 return {'error': e.message}
def un_sign(self, sign_session_id): """ 校验签名 session_id :param sign_session_id: :return: """ s = TimestampSigner(self._sign_key) try: session_id = s.unsign(sign_session_id, max_age=self.time_out) return session_id except SignatureExpired as e: # 处理签名超时 raise Exception(e.message) except BadTimeSignature as e: # 处理签名错误 raise Exception(e.message)
def unsign(self, signed_value, salt): """ Takes the signed value and returns it unsigned, if possible. If the signature is bad or if it expired, None is returned. """ if not signed_value: return None signer = TimestampSigner(self.secret, salt=salt) try: unsigned = signer.unsign(signed_value, max_age=self.max_age) # see http://pythonhosted.org/itsdangerous/#python-3-notes return unsigned.decode('utf-8') except (SignatureExpired, BadSignature): return None
def change_password(reset_token): """ Password change form; authenticates w/ token we've sent to user. """ s = TimestampSigner(os.getenv("SECRET_KEY"), salt="reset-password") error = "" try: email = s.unsign(reset_token, max_age=60*60*24).lower() # 24 hours except SignatureExpired: error = "expired-token" except BadTimeSignature: error = "invalid-token" if error: return render_template_custom("change-password.html", error=error) if request.method == "GET": return render_template_custom( 'change-password.html', error=error ) elif request.method == "POST": # the token is one we made. Whoever has it pwns this account retrieved_user = User.query.filter_by(email=email).first() if retrieved_user is None: abort(404, "Sorry, that user doesn't exist.") retrieved_user.set_password(request.form["confirm_new_pw"]) login_user(retrieved_user) db.session.commit() flash("Password changed.", "success") return redirect("/" + retrieved_user.url_slug)
def decrypt(self, payload, timestamp=False): result = None ts_error = None if(payload == None): ts_error = 'data is not valid.' else: if(timestamp == True): s1 = TimestampSigner(self.secret_key) try: # 3600 seconds in an hour result = s1.unsign(payload, max_age=3600) except SignatureExpired: ts_error = 'timestamp has expired.' except BadSignature: ts_error = 'data is not valid.' if(ts_error == None): try: s2 = URLSafeSerializer(self.secret_key) result = s2.loads(result) except BadSignature: result = 'data is not valid.' else: result = ts_error return result
class TokenManager(object): def __init__(self): """ Create a cypher to encrypt IDs and a signer to sign tokens.""" # Create cypher to encrypt IDs # and ensure >=16 characters # secret = app.config.get('SECRET_KEY') secret = 'SECRET_KEY' precursor = b'0123456789abcdef' if isinstance(secret, bytes): key = secret + precursor else: key = secret.encode("utf-8") + precursor self.cipher = AES.new(key[0:16], AES.MODE_ECB) # Create signer to sign tokens self.signer = TimestampSigner(secret) def encrypt_id(self, id): """ Encrypts integer ID to url-safe base64 string.""" # 16 byte integer str1 = '%016d' % id # encrypted data str2 = self.cipher.encrypt(str1.encode()) # URL safe base64 string with '==' str3 = base64.urlsafe_b64encode(str2) # return base64 string without '==' return str3[0:-2] def decrypt_id(self, encrypted_id): """ Decrypts url-safe base64 string to integer ID""" # Convert strings and unicode strings to bytes if needed if hasattr(encrypted_id, 'encode'): encrypted_id = encrypted_id.encode('ascii', 'ignore') try: str3 = encrypted_id + b'==' # --> base64 string with '==' # print('str3=', str3) str2 = base64.urlsafe_b64decode(str3) # --> encrypted data # print('str2=', str2) str1 = self.cipher.decrypt(str2) # --> 16 byte integer string # print('str1=', str1) return int(str1) # --> integer id except Exception as e: # pragma: no cover print('!!!Exception in decrypt_id!!!:', e) return 0 def generate_token(self, id): """ Return token with id, timestamp and signature""" # In Python3 we must make sure that bytes are converted to strings. # Hence the addition of '.decode()' return self.signer.sign(self.encrypt_id(id)).decode() def verify_token(self, token, expiration_in_seconds): """ Verify token and return (is_valid, has_expired, id). Returns (True, False, id) on success. Returns (False, True, None) on expired tokens. Returns (False, False, None) on invalid tokens.""" try: data = self.signer.unsign(token, max_age=expiration_in_seconds) is_valid = True has_expired = False id = self.decrypt_id(data) except SignatureExpired: is_valid = False has_expired = True id = None except BadSignature: is_valid = False has_expired = False id = None return (is_valid, has_expired, id)
def check_signature(signature, age): """Checks whether a timestamp signature is valid and under a given age.""" s = TimestampSigner(conf.get('cookie_secret')) return s.unsign(signature, max_age=age)
@app.route('/reset', methods=["POST"]) def do_password_reset(): try: token = str(request.form.get('token', "")) new_password = str(request.form.get('new_password', "")) token = base64.b64decode(token) except Exception, e: logger.error(e) return fail("error decoding token") if token and new_password: try: s = TimestampSigner(settings["secret_key"]) result = s.unsign(token, max_age=60*60*24) hashed_password = bcrypt.hashpw(new_password, bcrypt.gensalt(8)) urlfinder.update_password(result, hashed_password) except Exception, e: logger.error(e) return fail("error resetting password") return jsonify({"success": "password reset"}) @app.route('/<page_id>') def do_redirect(page_id=None): try: redirect_url = urlfinder.uid_to_url(page_id) urlfinder.increase_accessed(page_id) except: e = sys.exc_info()[0]