Beispiel #1
0
    def oauth2_start(self):
        if DEBUG_ROUTE:
            print("application:flow-register:oauth2:start",
                  get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug(
                "application:flow-register:oauth2:start %s",
                get_csrf_token(self.request),
            )
        if DEBUG_USERID:
            print("application:account:oauth2:start",
                  self.request.active_useraccount_id)

        if self.request.active_useraccount_id:
            return HTTPSeeOther("/application/account/home")

        authClient = OAuth2Session(
            OAUTH2__APP_KEY,
            redirect_uri=oauth2_utils.OAUTH2__URL_APP_FLOW_REGISTER_CALLBACK,
        )

        # Redirect user to the App for authorization
        authorization_url, state = authClient.authorization_url(
            oauth2_utils.OAUTH2__URL_AUTHORITY_FLOWA_AUTHORIZATION)

        return HTTPSeeOther(authorization_url)
Beispiel #2
0
    def token(self):
        """
        this is called in two contexts:
        1- a loggedin user is getting an access token for their client key/secret combo
        2- a client app is exchanging an authorization code for an access token
        """
        if DEBUG_ROUTE:
            print("authority:oauth2:token", get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug("authority:oauth2:token %s",
                      get_csrf_token(self.request))
        try:
            user_id = self.request.active_useraccount_id
            if user_id is not None:
                credentials = dict(user_id=user_id)
            else:
                credentials = None

            oauth2Provider = new_oauth2Provider(self.request)
            rval = oauth2Provider.endopoint__token(credentials=credentials)
            return rval

        except HTTPException:
            raise
        except Exception as exc:
            # raise custom errors in production
            raise exc
Beispiel #3
0
 def account_logout(self):
     if DEBUG_ROUTE:
         print("authority:account:logout", get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:account:logout %s",
                   get_csrf_token(self.request))
     if self.request.active_useraccount_id:
         self.request.session.invalidate()
     return HTTPSeeOther("/authority/account/login-form")
Beispiel #4
0
 def account_home(self):
     if DEBUG_ROUTE:
         print("authority:account:home", get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:account:home %s",
                   get_csrf_token(self.request))
     if not self.request.active_useraccount_id:
         return HTTPSeeOther("/authority/account/login-form")
     return "authority|home|user=%s" % self.request.active_useraccount_id
Beispiel #5
0
 def whoami(self):
     "This is used for writing tests"
     if DEBUG_ROUTE:
         print("whoami", get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("whoami %s", get_csrf_token(self.request))
     if DEBUG_USERID:
         print("whoami", self.request.active_useraccount_id)
     return "%s" % (self.request.active_useraccount_id or "")
Beispiel #6
0
 def account_login_form(self):
     if DEBUG_ROUTE:
         print("authority:account:login-form", get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:account:login-form %s",
                   get_csrf_token(self.request))
     if self.request.active_useraccount_id:
         return HTTPSeeOther("/authority/account/home")
     return "authority|login-form"
Beispiel #7
0
    def revoke_token(self):
        """
        revoke the User's token on the server
        """
        if DEBUG_ROUTE:
            print("application:account:revoke-token",
                  get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug("application:account:revoke-token %s",
                      get_csrf_token(self.request))
        if not self.request.active_useraccount_id:
            return HTTPSeeOther("/application/account/login-form")
        if self.request.active_useraccount_id != USERID_ACTIVE__APPLICATION:
            raise ValueError("not the expected user!")

        # what is our token?
        clientToken = (
            self.request.dbSession.query(Developer_OAuth2Client_BearerToken).
            filter(
                Developer_OAuth2Client_BearerToken.useraccount_id ==
                USERID_ACTIVE__APPLICATION,
                Developer_OAuth2Client_BearerToken.original_grant_type ==
                "authorization_code",
                Developer_OAuth2Client_BearerToken.is_active == True,  # noqa
            ).first())
        if not clientToken:
            raise ValueError("no token for this user!")

        apiClient = oauth2_utils.CustomApiClientB(
            app_key=oauth2_model.OAUTH2__APP_KEY,
            app_secret=oauth2_model.OAUTH2__APP_SECRET,
            oauth_version=2,
        )
        token_result = apiClient.revoke_access_token(
            token=clientToken.access_token)
        assert token_result is True

        clientToken.timestamp_revoked = self.request.datetime
        clientToken.is_active = False
        self.request.dbSession.flush()

        # just make sure it's marked as inactive on the server...
        _serverToken = (
            self.request.dbSession.query(Developer_OAuth2Server_BearerToken).
            filter(
                Developer_OAuth2Server_BearerToken.useraccount_id ==
                USERID_ACTIVE__AUTHORITY,
                Developer_OAuth2Server_BearerToken.original_grant_type ==
                "authorization_code",
                Developer_OAuth2Server_BearerToken.is_active == False,  # noqa
                Developer_OAuth2Server_BearerToken.access_token ==
                clientToken.access_token,
            ).first())
        assert _serverToken is not None

        return "revoked_token"
Beispiel #8
0
 def account_login_submit(self):
     if DEBUG_ROUTE:
         print("authority:account:login-submit",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:account:login-submit %s",
                   get_csrf_token(self.request))
     self.request.session[
         "active_useraccount_id"] = USERID_ACTIVE__AUTHORITY
     return HTTPSeeOther("/authority/account/home")
Beispiel #9
0
    def oauth1_start(self):
        if DEBUG_ROUTE:
            print("application:flow-register:oauth1:start",
                  get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug(
                "application:flow-register:oauth1:start %s",
                get_csrf_token(self.request),
            )
        if DEBUG_USERID:
            print("application:account:oauth1:start",
                  self.request.active_useraccount_id)

        if self.request.active_useraccount_id:
            return HTTPSeeOther("/application/account/home")

        # setup the session storage
        if "3rdparty-app_oauth" not in self.request.session:
            self.request.session["3rdparty-app_oauth"] = {}

        # Store whether this OAuth attempt is to authenticate or authorize, so we
        # can provide the right try again link in case any of our calls to the
        # Twitter API fail.
        self.request.session["3rdparty-app_oauth"]["mode"] = "authorize"

        # If there was a valid ``next`` param in the query string, store it in the
        # session so we can redirect to it later on.
        self.request.session["3rdparty-app_oauth"][
            "next"] = self.request.params.get("next")

        app_data = get_ApiExampleAppData()
        apiClient = CustomApiClient(
            app_key=app_data["client_key"],
            app_secret=app_data["client_secret"],
            client_args={"verify": False},
        )
        try:
            auth_props = apiClient.get_authentication_tokens(
                callback_url=app_data["callback_uri"])
            self.request.session["3rdparty-app_oauth"][
                "auth_url"] = auth_props["auth_url"]
            self.request.session["3rdparty-app_oauth"][
                "oauth_token"] = auth_props["oauth_token"]
            self.request.session["3rdparty-app_oauth"][
                "oauth_token_secret"] = auth_props["oauth_token_secret"]
            redirect_url = auth_props["auth_url"]
            return HTTPSeeOther(location=redirect_url)

        except ApiAuthError as exc:
            raise ValueError(
                "There are issues connecting with the Example Server API.")

        except ApiError as exc:
            error_dict = {"error": 1, "error_message": exc.msg}
            raise ValueError(exc.msg)
Beispiel #10
0
 def account_home(self):
     if DEBUG_ROUTE:
         print("application:account:home", get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("application:account:home %s",
                   get_csrf_token(self.request))
     if DEBUG_USERID:
         print("application:account:home",
               self.request.active_useraccount_id)
     if not self.request.active_useraccount_id:
         return HTTPSeeOther("/application/account/login-form")
     return "application|home|user=%s" % self.request.active_useraccount_id
Beispiel #11
0
 def register(self):
     if DEBUG_ROUTE:
         print("application:flow-register", get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("application:flow-register %s",
                   get_csrf_token(self.request))
     if DEBUG_USERID:
         print("application:flow-register",
               self.request.active_useraccount_id)
     if self.request.active_useraccount_id:
         return HTTPSeeOther("/application/account/home")
     return HTTPSeeOther("/application/flow-register/oauth2/start")
Beispiel #12
0
 def account_login_submit(self):
     if DEBUG_ROUTE:
         print("application:account:login-submit",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("application:account:login-submit %s",
                   get_csrf_token(self.request))
     if DEBUG_USERID:
         print("application:account:login-submit",
               self.request.active_useraccount_id)
     self.request.session[
         "active_useraccount_id"] = USERID_ACTIVE__APPLICATION
     return HTTPSeeOther("/application/account/home")
Beispiel #13
0
 def account_login_form(self):
     if DEBUG_ROUTE:
         print("application:account:login-form",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("application:account:login-form %s",
                   get_csrf_token(self.request))
     if DEBUG_USERID:
         print("application:account:login-form",
               self.request.active_useraccount_id)
     if self.request.active_useraccount_id:
         return HTTPSeeOther("/application/account/home")
     return "application|login-form"
Beispiel #14
0
 def authorized_callback_success(self):
     if DEBUG_ROUTE:
         print(
             "application:flow-register:oauth2:authorized-callback-success",
             get_csrf_token(self.request),
         )
     if LOG_ROUTE:
         log.debug(
             "application:flow-register:oauth2:authorized-callback-success %s",
             get_csrf_token(self.request),
         )
     if not self.request.active_useraccount_id:
         return HTTPSeeOther("/application/account/login-form")
     return ("example_app|authorized-callback-success|user=%s" %
             self.request.active_useraccount_id)
Beispiel #15
0
    def registration_authorized_callback_success(self):
        if DEBUG_ROUTE:
            print(
                "application:flow-register:oauth1:authorized-callback-success",
                get_csrf_token(self.request),
            )
        if LOG_ROUTE:
            log.debug(
                "application:flow-register:oauth1:authorized-callback-success|user=%s",
                get_csrf_token(self.request),
            )
        if DEBUG_USERID:
            print(
                "application:account:register:oauth1:authorized-callback-success",
                self.request.active_useraccount_id,
            )
        if not self.request.active_useraccount_id:
            return HTTPSeeOther("/application/account/login-form")

        # so let's just check to ensure we have the right number of active tokens (Client)
        _clientTokens = (
            self.request.dbSession.query(Developer_oAuth1Client_TokenAccess).
            filter(
                Developer_oAuth1Client_TokenAccess.useraccount_id ==
                USERID_ACTIVE__APPLICATION,
                Developer_oAuth1Client_TokenAccess.is_active == True,  # noqa
            ).all())
        assert len(_clientTokens) == 1

        # so let's just check to ensure we have the right number of active tokens (Server)
        _serverTokens = (
            self.request.dbSession.query(Developer_oAuth1Server_TokenAccess).
            filter(
                Developer_oAuth1Server_TokenAccess.useraccount_id ==
                USERID_ACTIVE__AUTHORITY,
                Developer_oAuth1Server_TokenAccess.is_active == True,  # noqa
            ).all())
        assert len(_serverTokens) == 1

        # and make sure the client/server tokens are the same
        assert (_serverTokens[0].oauth_token_secret ==
                _clientTokens[0].oauth_token_secret)
        assert _serverTokens[0].oauth_token == _clientTokens[0].oauth_token
        assert _serverTokens[0]._realms == _clientTokens[0]._realms

        # yep, we good
        return ("application|register|authorized-callback-success|user=%s" %
                self.request.active_useraccount_id)
Beispiel #16
0
    def _authorize_process(self):
        """process the form"""
        try:
            (result, formStash) = formhandling.form_validate(
                self.request,
                schema=Form_OAuthToken,
                csrf_token=get_csrf_token(self.request),
            )
            if not result:
                raise formhandling.FormInvalid()

            if formStash.results["submit"] == "deny":
                # process deny
                raise HTTPSeeOther("/account/home")

            # accept!
            # this is decorated by `catch_errors_and_unavailability` and will raise an `OAuth1Error`
            return self.request.workspace.oAuth1Provider.endpoint__authorize__authorize(
                self.request.workspace.oAuth1_data)

        except (OAuth1Error, formhandling.FormInvalid) as exc:
            if isinstance(exc, OAuth1Error):
                self.request.workspace.oAuth1_Error = exc
            return formhandling.form_reprint(self.request,
                                             self._authorize_print)
Beispiel #17
0
    def test_ok_with_good_csrf(self, pyramid_request):
        csrf_token = csrf.get_csrf_token(pyramid_request)
        pyramid_request.POST["csrf_token"] = csrf_token
        schema = ExampleCSRFSchema().bind(request=pyramid_request)

        # Does not raise
        schema.deserialize({})
Beispiel #18
0
 def oauth2_revoke_token(self):
     if DEBUG_ROUTE:
         print("authority:oauth2:revoke_token",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:oauth2:revoke_token %s",
                   get_csrf_token(self.request))
     try:
         oauth2Provider = new_oauth2Provider(self.request)
         rval = oauth2Provider.endpoint__revoke_token()
         return rval
     except HTTPException:
         raise
     except Exception as exc:
         # raise custom errors in production
         raise exc
Beispiel #19
0
 def obtain_token(self):
     """this default version calculates the client credentials as needed"""
     if DEBUG_ROUTE:
         print("authority:oauth2:flow_b:obtain_token",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:oauth2:flow_b:obtain_token %s",
                   get_csrf_token(self.request))
     try:
         oauth2Provider = new_oauth2Provider(self.request)
         rval = oauth2Provider.endopoint__token(credentials=None)
         return rval
     except HTTPException:
         raise
     except Exception as exc:
         # raise custom errors in production
         raise exc
Beispiel #20
0
    def authorize(self):
        if DEBUG_ROUTE:
            print("authority:oauth1:authorize", get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug("authority:oauth1:authorize %s",
                      get_csrf_token(self.request))
        if DEBUG_USERID:
            print("authority:oauth1:authorize",
                  self.request.active_useraccount_id)
        if not self.request.active_useraccount_id:
            return HTTPSeeOther("/authority/account/login-form")
        try:
            # no matter what we do, we need to grab this data
            oauth1Provider = new_oauth1Provider(self.request)

            # this is decorated by `catch_errors_and_unavailability` and will raise an `OAuth1Error`
            oauth1_data = oauth1Provider.extract__endpoint_authorize_data()

            # grab the token to show the user or process
            oauth1_TokenRequest = (
                self.request.dbSession.query(
                    Developer_oAuth1Server_TokenRequest).filter(
                        Developer_oAuth1Server_TokenRequest.oauth_token ==
                        oauth1_data["credentials"]["resource_owner_key"],
                        Developer_oAuth1Server_TokenRequest.is_active ==
                        True,  # noqa
                    ).first())
            if not oauth1_TokenRequest:
                raise ValueError("invalid token")

            self.request.workspace.oAuth1Provider = oauth1Provider
            self.request.workspace.oAuth1_data = oauth1_data
            self.request.workspace.oAuth1_TokenRequest = oauth1_TokenRequest

            if self.request.method == "POST":
                # this can raise an `OAuth1Error`, but it should be caught
                return self._authorize_process()
            return self._authorize_print()

        except OAuth1Error as exc:
            self.request.workspace.oAuth1_Error = exc
            return render_to_response(
                "templates/authorize-error.mako",
                {},
                self.request,
            )
Beispiel #21
0
 def obtain_token(self):
     """this endpoint does not accept client_credentials"""
     if DEBUG_ROUTE:
         print("authority:oauth2:flow_c:token_limited",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:oauth2:flow_c:token_limited %s",
                   get_csrf_token(self.request))
     try:
         oauth2Provider = new_oauth2ProviderLimited(self.request)
         rval = oauth2Provider.endopoint__token()
         return rval
     except HTTPException:
         raise
     except Exception as exc:
         # raise custom errors in production
         raise exc
Beispiel #22
0
 def access_token(self):
     if DEBUG_ROUTE:
         print("authority:oauth1:access_token",
               get_csrf_token(self.request))
     if LOG_ROUTE:
         log.debug("authority:oauth1:access_token %s",
                   get_csrf_token(self.request))
     if DEBUG_USERID:
         print("authority:oauth1:access_token",
               self.request.active_useraccount_id)
     try:
         provider = new_oauth1Provider(self.request)
         return provider.endpoint__access_token()
     except HTTPException:
         raise
     except Exception as exc:
         # raise custom errors in production
         raise exc
Beispiel #23
0
    def protected_resource(self):
        """the resource is protected behind an oauth2 token validation."""
        if DEBUG_ROUTE:
            print("authority:oauth2:protected_resource",
                  get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug("authority:oauth2:protected_resource %s",
                      get_csrf_token(self.request))

        oauth2Provider = new_oauth2Provider(self.request)
        scopes = ["platform.actor"]
        valid, req = oauth2Provider.verify_request(scopes)
        if not valid:
            raise HTTPForbidden()

        # dbTokens = self.request.dbSession.query(Developer_OAuth2Server_BearerToken).all()
        # pdb.set_trace()
        return "protected_resource"
Beispiel #24
0
    def fetch_protected_resource(self):
        """
        A user must log into ExampleApp and have an authorized token for the Authority system.

        This route will load the token and use it to make an oAuth2 request against the Authority system.
        """
        if DEBUG_ROUTE:
            print(
                "application:account:fetch-protected-resource",
                get_csrf_token(self.request),
            )
        if LOG_ROUTE:
            log.debug(
                "application:account:fetch-protected-resource %s",
                get_csrf_token(self.request),
            )
        if not self.request.active_useraccount_id:
            return HTTPSeeOther("/application/account/login-form")

        # what is our token?
        clientToken = (
            self.request.dbSession.query(Developer_OAuth2Client_BearerToken).
            filter(
                Developer_OAuth2Client_BearerToken.useraccount_id ==
                self.request.active_useraccount_id,
                Developer_OAuth2Client_BearerToken.original_grant_type ==
                "authorization_code",
                Developer_OAuth2Client_BearerToken.is_active == True,  # noqa
            ).first())
        if not clientToken:
            raise ValueError("no token for this user!")

        token_dict = {
            "access_token": clientToken.access_token,
            "token_type": "Bearer"
        }
        sess = OAuth2Session(client_id=OAUTH2__APP_KEY, token=token_dict)
        resp = sess.request(
            "GET", oauth2_utils.OAUTH2__URL_AUTHORITY_PROTECTED_RESOURCE)
        if resp.status_code != 200:
            raise ValueError("invalid")
        return resp.text
Beispiel #25
0
    def obtain_token_alt(self):
        """
        this alt version pre-calculates the client_credentials.

        1. 'grant_type' in request.POST, grant_type=='client_credentials'
        2. HTTP Basic Authorization contains
            username: client_id
            password: client_secret
        """
        if DEBUG_ROUTE:
            print("authority:oauth2:flow_b:obtain_token_alt",
                  get_csrf_token(self.request))
        if LOG_ROUTE:
            log.debug(
                "authority:oauth2:flow_b:obtain_token_alt %s",
                get_csrf_token(self.request),
            )
        try:
            # turn this into a username/password
            # HTTPBasicCredentials(username=u'OAUTH2APPKEYOAUTH2APPKEYOAUTH2APPKEYOAUTH2APPKEY', password=u'OAUTH2__APP_SECRET')
            credentials = extract_http_basic_credentials(self.request)
            credentials = ({
                "username": credentials.username,
                "password": credentials.password
            } if credentials else {})

            # logging.basicConfig()
            # _loggingOld = logging.getLogger().getEffectiveLevel()
            # logging.getLogger().setLevel(logging.DEBUG)

            oauth2Provider = new_oauth2Provider(self.request)
            rval = oauth2Provider.endopoint__token(credentials=credentials)
            return rval
        except HTTPException:
            raise
        except Exception as exc:
            # raise custom errors in production
            raise exc
Beispiel #26
0
def userLogin(request, login, password, appName):
    """
    This and 'auth.logout' are the only rpc methods that does not subclass
    RpcBase for they must be invoked without valid user session.
    """
    sess = DBSession()
    user = sess.query(Party).filter_by(login=login).first()

    if not user or not user.verifyPassword(password):
        raise RPCUserError('登录失败,请检查用户名和密码!')

    # Only those with defined permission are allowed
    if not user.extraData or appName not in user.extraData:
        raise RPCNotAllowedError('您无权登录当前应用。')

    # after user is authenticated, we cache the user object in redis
    sess.expunge_all()  # detach from session
    request.session['user'] = user

    # copy so that we do not persist the token in the session user object
    ret = user.extraData[appName].copy()
    ret['csrfToken'] = get_csrf_token(request)
    return ret
Beispiel #27
0
def like_post_json(context: PostResource, request):
    """ JSON `like` action.

    This action is CSRF-safe thanks to:

    - Accepting only POST requests
    - Browsers cannot submit JSON from forms
      (only ``application/x-www-form-urlencoded``)
    - CORS/SOP prevent scripts on `external pages` from posting
      unless a CORS policy allows it.
    - Requires a CSRF-token

    In addition the user must have permission to perform the action.

    Abbreviations:

    - CORS = Cross-Origin Resource Sharing
    - SOP = Same Origin Policy
    """

    request_body: dict = request.json_body

    # In case there is a CORS policy in place we also require the CSRF token
    # to be included in the JSON request.
    #
    # We can get the same effect by setting require_csrf=True which will
    # require the request to include an X-CSRF-Token header.
    #
    # Calling pyramid.csrf.check_csrf_token would also achieve the same thing
    # by checking the X-CSRF-Token header.
    csrf_token = request_body.get('csrf_token', '')
    expected_csrf_token = get_csrf_token(request)
    if not hmac.compare_digest(csrf_token, expected_csrf_token):
        raise BadCSRFToken()

    post = db.post.like_post(request.db, context.post.post_id)
    return post
Beispiel #28
0
def deferred_csrf_token(_node, kw):
    request = kw.get("request")
    return get_csrf_token(request)
Beispiel #29
0
    def _callFUT(self, *args, **kwargs):
        from pyramid.csrf import get_csrf_token

        return get_csrf_token(*args, **kwargs)
Beispiel #30
0
 def csrfToken(self):
     return get_csrf_token(self.request) \
         if self.request.authenticated else None
Beispiel #31
0
 def _callFUT(self, *args, **kwargs):
     from pyramid.csrf import get_csrf_token
     return get_csrf_token(*args, **kwargs)