Exemplo n.º 1
0
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')
Exemplo n.º 2
0
 def generate_token(self, playload):
     """
     :param playload: 负载,也就是你要序列化的数据,不要用关键数据(如密码等)做playload
     :return: token字符串
     """
     serializer = URLSafeTimedSerializer(self.secret_key, self.salt)
     return serializer.dumps(playload)
Exemplo n.º 3
0
 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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
def serialize(data, secret=None):
    if secret is None:
        secret = current_app.config["SECRET_KEY"]
    s = URLSafeTimedSerializer(secret)
    return s.dumps(data)
Exemplo n.º 7
0
def serialize(data):
    secret = current_app.config['SECRET_KEY']
    s = URLSafeTimedSerializer(secret)
    return s.dumps(data)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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