def __init__( self, *, name: str, secret_key: str, backend: Type[SessionBackend], data_model: Type[BaseModel], scheme_name: Optional[str] = None, auto_error: bool = True, max_age: int = 14 * 24 * 60 * 60, # 14 days in seconds expires: datetime = None, path: str = "/", domain: str = None, secure: bool = False, httponly: bool = True, samesite: str = "lax", ): self.model: APIKey = APIKey(**{"in": APIKeyIn.cookie}, name=name) self.scheme_name = scheme_name or self.__class__.__name__ self.auto_error = auto_error self.signer = URLSafeTimedSerializer(secret_key, salt=name) self.backend = backend self.data_model = data_model self.max_age = max_age self.expires = expires self.path = path self.domain = domain self.secure = secure self.httponly = httponly self.samesite = samesite
def decorated_view(*args, **kw): auth = request.headers.get('Authorization') if not auth: return json_error_response(401, 'Authorization required') try: auth_type, auth_token = auth.split() except ValueError: return json_error_response(401, 'Invalid authentication header') if auth_type.lower() != 'basic': return json_error_response(401, 'Invalid authentication type') signer_kw = {'digest_method': hashlib.sha512} serializer = URLSafeTimedSerializer( current_app.secret_key, salt=current_app.config['TOKEN_SALT'], signer_kwargs=signer_kw, ) try: name = serializer.loads(auth_token, current_app.config['TOKEN_MAX_AGE']) user = get_user(name) if not user: return json_error_response(401, 'Invalid token') g.user = user return func(*args, **kw) except SignatureExpired: return json_error_response(400, 'Token expired') except BadSignature: return json_error_response(401, 'Invalid token')
def check_token(token: str, secret: str, max_age: int) -> TokenCheckResult: """Check token validity, returns validation result with payload if token is valid. :param token: token to check :type token: str :param secret: secret that was used to generate token :type secret: str :param max_age: max age of token :type max_age: int :return: validation result :rtype: TokenCheckResult """ serializer = URLSafeTimedSerializer(secret) payload = None is_error = True msg = None try: payload = serializer.loads(token, max_age=max_age) is_error = False except SignatureExpired as e: msg = _( "token expired, it's valid for 48 hrs and it was generated on %(date)s", date=e.date_signed, ) except BadSignature: msg = _('invalid token') return TokenCheckResult(is_error, message=msg, payload=payload)
def email_confirmation_begin(): if request.method == 'POST': if not current_user.email: abort(400) payload = {'id': current_user.id} serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) token = serializer.dumps(payload) html_body = render_template('email/email_confirmation.html', token=token) subject = _('Email confirmation at Brewlog') current_app.queue.enqueue( 'brewlog.tasks.send_email', current_app.config['EMAIL_SENDER'], [current_user.email], subject, html_body, ) flash( _( 'confirmation email has been sent to %(email)s, please check your ' 'mailbox', email=current_user.email, ), category='success', ) return redirect(url_for('.details', user_id=current_user.id)) return render_template('account/email_confirm_begin.html')
def update_password(self, http_context): """ Update user's password in the auth provider. :param http_context: HttpContext :type http_context: HttpContext """ serial = json.loads(http_context.body.decode())['serial'] password = json.loads(http_context.body.decode())['password'] if serial and password: with open(SECRET_FILE, 'r') as f: secret = f.read().strip('\n') serializer = URLSafeTimedSerializer(secret) user = serializer.loads(serial, max_age=900)['user'] auth_provider = AuthenticationService.get( self.context).get_provider() answer = auth_provider.update_password(user, password) if not answer: http_context.respond_forbidden() return [b'403 Forbidden'] else: http_context.respond_ok() return [b'200 OK']
def generate_token(self, playload): """ :param playload: 负载,也就是你要序列化的数据,不要用关键数据(如密码等)做playload :return: token字符串 """ serializer = URLSafeTimedSerializer(self.secret_key, self.salt) return serializer.dumps(playload)
def load_token(token): duration = app.config['REMEMBER_COOKIE_DURATION'].total_seconds() serializer = URLSafeTimedSerializer(app.secret_key) data = serializer.loads(token, max_age=duration) user_uid = data[0] return user_model.query.get(user_uid)
def verify_auth_token(token, max_age=EXPIRATION_SECONDS): s = URLSafeTimedSerializer(SK).signer(SK) try: token = token.encode('utf-8') user_id = s.unsign(token, max_age=max_age) user_id = user_id.decode('utf-8') except SignatureExpired: return None # valid token, but expired except BadSignature: return None # invalid token return User(user_id)
def save(self): user = BrewerProfile.get_by_email(self.email1.data) if user is not None and user.email_confirmed: payload = {'id': user.id} serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) token = serializer.dumps(payload) html_body = render_template('email/password_reset.html', token=token) sender = current_app.config['EMAIL_SENDER'] subject = str(_('Request to reset password at Brewlog')) current_app.queue.enqueue( 'brewlog.tasks.send_email', sender, [user.email], subject, html_body, ) return True return False
def confirm_token(self, token, expired=86400): """ 验证token :param token: generate_validate_token产生的字符串 :param expired: 过期时间,以秒为单位 :return: 成功返回负载数据,失败返回错误码 """ serializer = URLSafeTimedSerializer(self.secret_key, self.salt) try: data = serializer.loads(token, max_age=expired) except BadData as e: return TokenException(e) # 签名验证通过,返回原始数据 return data
def generate_token(payload: str) -> str: """Generate token for authenticating and autorising client. The token is URL-safe and includes timestamp. :param payload: data to be serialised :type payload: str :return: token string :rtype: str """ signer_kw = {'digest_method': hashlib.sha512} serializer = URLSafeTimedSerializer( current_app.secret_key, salt=current_app.config['TOKEN_SALT'], signer_kwargs=signer_kw, ) return serializer.dumps(payload)
def __init__(self, sent_from=gmail_user, gmail_password=gmail_password, to=[email_reviewer]): self.sent_from = sent_from self.gmail_password = gmail_password.encode('utf-8') self.gmail_password = base64.b64encode(self.gmail_password) self.timed_safe_serial = URLSafeTimedSerializer( 'new_plan_confirmation') self.to = to self.subject = 'sca_project_test_email at: ' + str( datetime.datetime.now()) self.email_text = ''
def serializerCompressed(key): return URLSafeTimedSerializer(secret_key=key, salt='cookie-session', serializer=TaggedJSONSerializer(), signer_kwargs={ 'key_derivation': 'hmac', 'digest_method': hashlib.sha1 })
def get_serializer(self): try: token_secret = api.portal.get_registry_record( "token_secret", interface=IRerUfficiostampaSettings) token_salt = api.portal.get_registry_record( "token_salt", interface=IRerUfficiostampaSettings) except (KeyError, InvalidParameterError): return None if not token_secret or not token_salt: None return URLSafeTimedSerializer(token_secret, token_salt)
def send_password_reset(self, http_context): """ Sends upstream a request to check if a given email exists, in order to send a password reset link per email. :param http_context: HttpContext :type http_context: HttpContext """ mail = json.loads(http_context.body.decode())['mail'] username = self.auth_provider.check_mail(mail) if username: with open(SECRET_FILE, 'r') as f: secret = f.read().strip('\n') serializer = URLSafeTimedSerializer(secret) serial = serializer.dumps({'user': username, 'email': mail}) origin = http_context.env['HTTP_ORIGIN'] link = f'{origin}/view/reset_password/{serial}' self.notifications.send_password_reset(mail, link)
def check_serial(self, http_context): """ Check if the serial in a given reset link is valid :param http_context: HttpContext :type http_context: HttpContext """ serial = json.loads(http_context.body.decode())['serial'] if serial: try: with open(SECRET_FILE, 'r') as f: secret = f.read().strip('\n') serializer = URLSafeTimedSerializer(secret) # Serial can not be used after 15 min serializer.loads(serial, max_age=900) http_context.respond_ok() return [b'200 OK'] except (SignatureExpired, BadTimeSignature, BadSignature) as err: logging.warning('Password reset link not valid or expired') http_context.respond_not_found() return [b'Link not valid'] return False
SIGNING_SECRET, OAUTH_BLIZZARD_CLIENT_ID, OAUTH_BLIZZARD_CLIENT_SECRET, OAUTH_DISCORD_CLIENT_ID, OAUTH_DISCORD_CLIENT_SECRET, OAUTH_REDIRECT_PATH, OAUTH_REDIRECT_HOST, ) from .config_classes import GuildConfig from .i18n import _, ngettext, CurrentLocale from .models import User, GuildConfigJson, HighscoreCron from .utils import run_sync logger = logging.getLogger(__name__) serializer = URLSafeTimedSerializer(SIGNING_SECRET) TOKEN_MAX_AGE = 1800 if not DEVELOPMENT else 3600000 app = QuartTrio(__name__) # HACK: these three are set by Orisa in orisa.py. send_ch = None client = None orisa = None app.debug = DEVELOPMENT async def render_message(message, is_error=False): return await render_template(
def unserialize(data, secret=None, max_age=432000): if secret is None: secret = current_app.config["SECRET_KEY"] s = URLSafeTimedSerializer(secret) return s.loads(data, max_age=max_age)
def serialize(data, secret=None): if secret is None: secret = current_app.config["SECRET_KEY"] s = URLSafeTimedSerializer(secret) return s.dumps(data)
def serializerNormal(key): return URLSafeTimedSerializer(key)
def serialize(data): secret = current_app.config['SECRET_KEY'] s = URLSafeTimedSerializer(secret) return s.dumps(data)
def unserialize(data, max_age=432000): secret = current_app.config['SECRET_KEY'] s = URLSafeTimedSerializer(secret) return s.loads(data, max_age=max_age)
from flask_security.decorators import login_required, roles_required from flask_security.utils import login_user, logout_user, hash_password from flask_security.core import current_user from flask_login import login_user, logout_user from flask_mail import Message from itsdangerous.url_safe import URLSafeTimedSerializer from itsdangerous.exc import BadSignature, SignatureExpired from jinja2 import Markup from datetime import datetime confirm_time = 3 # hours invalid_token_markup = Markup(f"""<h3>Время для подтверждения истекло</h3><br> Проведите повторную регистрацию для подтверждения""") signer = URLSafeTimedSerializer(secret_key=app.config.get("SECRET_KEY")) bp_auth = Blueprint('auth', __name__, url_prefix='/auth', template_folder="templates") # !!!! Переделать - убрать тут и добавить в html def collect_warnings(form_errors) -> list: """Collect all warning in form and return :returns list of strings""" warnings = [] for errors in form_errors.values(): warnings += errors return warnings @bp_auth.route("/register", methods=["POST", "GET"])
class Emails(): def __init__(self, sent_from=gmail_user, gmail_password=gmail_password, to=[email_reviewer]): self.sent_from = sent_from self.gmail_password = gmail_password.encode('utf-8') self.gmail_password = base64.b64encode(self.gmail_password) self.timed_safe_serial = URLSafeTimedSerializer( 'new_plan_confirmation') self.to = to self.subject = 'sca_project_test_email at: ' + str( datetime.datetime.now()) self.email_text = '' def email_body( self, new_plan, email_text=DEFAULT_EMAIL_BODY, ): form = NewPlanForm() body = 'sca_project_test_email at: ' + str(datetime.datetime.now()) body += '\n This is a test email from Python Dev App.' body += '\n user request: ' + new_plan.username body += '\n plan name: ' + new_plan.plan_name body += '\n plan time frame: ' + str(new_plan.plan_timeframe) body += '\n plan link: ' + new_plan.plan_url # DEV Include a link. body += '\n\n Click this link to confirm new plan and add to the database: ' body += '\n\n url safe timed serializer:' + self.timed_safe_serial.dumps( [1]) email_text = """ From: %s To: %s Subject: %s %s """ % (self.sent_from, ", ".join(self.to), self.subject, body) self.email_text = email_text # request.method == 'POST': # Protecting Proprietary or Sensitive Information. ## Some plan review has already happened. ## Endangered species locations. ## How to review proprietary and sensitive information.... ## Maybe include a disclaimer in the message. # @app.route('/login', methods=['POST']) def email_send(self, new_plan): try: self.email_body(new_plan) smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465) smtp_server.ehlo() smtp_server.login(self.sent_from, base64.b64decode(self.gmail_password).decode()) smtp_server.sendmail(self.sent_from, self.to, self.email_text) smtp_server.close() print("Email sent successfully!") return True except Exception as ex: print("Something went wrong….", ex) return False
def decode_token(): request = getRequest() secret = request.form.get("secret", "") if not secret: return { "error": _( "unsubscribe_confirm_secret_null", default= u"Unable to manage subscriptions. Token not present.", # noqa ) } try: token_secret = api.portal.get_registry_record( "token_secret", interface=IRerUfficiostampaSettings) token_salt = api.portal.get_registry_record( "token_salt", interface=IRerUfficiostampaSettings) except (KeyError, InvalidParameterError): return { "error": _( "unsubscribe_confirm_secret_token_settings_error", default= u"Unable to manage subscriptions. Token keys not set in control panel.", # noqa ) } if not token_secret or not token_salt: return { "error": _( "unsubscribe_confirm_secret_token_settings_error", default= u"Unable to manage subscriptions. Token keys not set in control panel.", # noqa ) } serializer = URLSafeTimedSerializer(token_secret, token_salt) try: data = serializer.loads(secret, max_age=86400) except SignatureExpired: return { "error": _( "unsubscribe_confirm_secret_expired", default=u"Unable to manage subscriptions. Token expired.", ) } except BadSignature: return { "error": _( "unsubscribe_confirm_secret_invalid", default=u"Unable to manage subscriptions. Invalid token.", ) } record_id = data.get("id", "") email = data.get("email", "") if not record_id or not email: return { "error": _( "unsubscribe_confirm_invalid_parameters", default=u"Unable to manage subscriptions. Invalid parameters.", ) } tool = getUtility(ISubscriptionsStore) record = tool.get_record(record_id) if not record: return { "error": _( "unsubscribe_confirm_invalid_id", default=u"Unable to manage subscriptions. Invalid id.", ) } if record.attrs.get("email", "") != email: return { "error": _( "unsubscribe_confirm_invalid_email", default=u"Unable to manage subscriptions. Invalid email.", ) } return {"data": record}
def generate_auth_token(self): s = URLSafeTimedSerializer(SK).signer(SK) token = s.sign(self.id) token = token.decode('utf-8') return token
class SessionCookie(SecurityBase): def __init__( self, *, name: str, secret_key: str, backend: Type[SessionBackend], data_model: Type[BaseModel], scheme_name: Optional[str] = None, auto_error: bool = True, max_age: int = 14 * 24 * 60 * 60, # 14 days in seconds expires: datetime = None, path: str = "/", domain: str = None, secure: bool = False, httponly: bool = True, samesite: str = "lax", ): self.model: APIKey = APIKey(**{"in": APIKeyIn.cookie}, name=name) self.scheme_name = scheme_name or self.__class__.__name__ self.auto_error = auto_error self.signer = URLSafeTimedSerializer(secret_key, salt=name) self.backend = backend self.data_model = data_model self.max_age = max_age self.expires = expires self.path = path self.domain = domain self.secure = secure self.httponly = httponly self.samesite = samesite async def __call__(self, request: Request) -> Optional[SessionInfo]: # Get the signed session id from the session cookie signed_session_id = request.cookies.get(self.model.name) if not signed_session_id: return self.authentication_error() # Verify and timestamp the signed session id try: session_id = self.signer.loads( signed_session_id, max_age=self.max_age, return_timestamp=False, ) except (SignatureExpired, BadTimeSignature): return self.authentication_error() # Attempt to read the corresponding session data from the backend session_data = await self.backend.read(session_id) if not session_data: return self.authentication_error() session_data = SessionDataWrapper[self.data_model]( session_id=session_id, **session_data, ) # Retrieve the csrf token, if it doesn't exist then its a potential # csrf attack and remove the session frontend_signed_csrf_token = request.cookies.get(self.model.name + "csrf") if not frontend_signed_csrf_token: await self.backend.remove(session_id) return self.authentication_error() # Validate the csrf token, if not valid then its a potential csrf # attack and delete the session try: frontend_csrf_token = self.signer.loads( frontend_signed_csrf_token, max_age=self.max_age, return_timestamp=False, ) assert frontend_csrf_token == session_data.csrf_token except (SignatureExpired, BadTimeSignature, AssertionError): await self.backend.remove(session_id) return self.authentication_error() return session_data.session_id, session_data.data def authentication_error(self): if self.auto_error: raise HTTPException(status_code=403, detail="Not authenticated") else: return None async def create_session(self, data: Type[BaseModel], response: Response, prev_session_info: Optional[str] = None): session_data = SessionDataWrapper[self.data_model](data=data) if prev_session_info: await self.backend.remove(prev_session_info) await self.backend.write(session_data) response.set_cookie( key=self.model.name, value=self.signer.dumps(session_data.session_id), max_age=self.max_age, expires=self.expires, path=self.path, domain=self.domain, secure=self.secure, httponly=self.httponly, samesite=self.samesite, ) # Temporary csrf cookie setting response.set_cookie(key=self.model.name + "csrf", value=self.signer.dumps(session_data.csrf_token)) async def end_session(self, session_id: str, response: Response): response.delete_cookie(self.model.name) await self.backend.remove(session_id)