Example #1
0
    def confirm_account(self, confirmation_token):
        '''
        Confirms user in database
        '''
        try:
            # Decode token
            jwt_manager = JWTConfirmEmailManagerFactory.new()
            brl_user = jwt_manager.get_confirmed_user(confirmation_token)
            user = self.store.read_user(brl_user)
        except NotInStoreException:
            raise NotFoundException("User '%s' doesn't exist" % brl_user)
        if user.confirmation_token == confirmation_token:
            if not user.active:  # Do not re-send things if already activated
                try:
                    register_signup(self.store, brl_user)
                except Exception as exc:
                    logger.error("Can't register sign-up in background! %s" % str(exc))

            user.active = True
            user.confirmation_date = datetime.datetime.now()
            self.store.update_user(user)
            jwt_auth_manager = JWTCredentialsManagerFactory.new(self.store)
            token = jwt_auth_manager.get_token_for(brl_user)

            return token, brl_user, user.ga_client_id

        else:
            raise NotFoundException("Invalid user or token")
Example #2
0
    def _get_login_page(self, user):
        manager = JWTCredentialsManagerFactory.new(self.store)
        token = manager.get_token_for(user.ID)

        joined_date = user.joined_date.to_iso8601 if user and user.joined_date else ""
        get_vars = {"oauthlogin": 1,
                    "login": user.ID, "token": token,
                    "client_id": user.ga_client_id,
                    "email": user.email, "created_at": joined_date}
        return "%s/accounts/login?%s" % (BII_WEB_DOMAIN_URL, urllib.urlencode(get_vars))
Example #3
0
 def authenticate(self, brl_user, password):
     """ Create a "profile" object (object to encrypt) and expiration time.
     Then return the JWT token Expiration time as a UTC UNIX timestamp
     (an int) or as a datetime"""
     try:
         brl_user = BRLUser(brl_user)
     except InvalidNameException:
         raise AuthenticationException("Wrong user or password")
     self._check_password(brl_user, password)
     manager = JWTCredentialsManagerFactory.new(self.store)
     token = manager.get_token_for(brl_user)
     return brl_user, token
Example #4
0
    def test_invalid_token(self):
        '''Obtain a valid token and then change password. Token must be invalid'''
        brl_user, token_1 = self.user_service.authenticate(self.brl_user, self.plain_password)
        # Check the token is valid
        manager = JWTCredentialsManagerFactory.new(self.store)
        brl_user_test = manager.get_user(token_1)
        self.assertEqual(brl_user, brl_user_test)
        sleep(0.1)  # Sleep a moment and change the password

        # Now change password and re-check old token
        self.user_service.change_password(self.brl_user, self.plain_password, "Newp@sW0rd")

        # Check the token is invalid (can't authenticate)
        self.assertRaises(DecodeError, manager.get_user, token_1)
Example #5
0
    def _get_login_page(self, user):
        manager = JWTCredentialsManagerFactory.new(self.store)
        token = manager.get_token_for(user.ID)

        joined_date = user.joined_date.to_iso8601 if user and user.joined_date else ""
        get_vars = {
            "oauthlogin": 1,
            "login": user.ID,
            "token": token,
            "client_id": user.ga_client_id,
            "email": user.email,
            "created_at": joined_date
        }
        return "%s/accounts/login?%s" % (BII_WEB_DOMAIN_URL,
                                         urllib.urlencode(get_vars))
Example #6
0
    def test_invalid_token(self):
        '''Obtain a valid token and then change password. Token must be invalid'''
        brl_user, token_1 = self.user_service.authenticate(
            self.brl_user, self.plain_password)
        # Check the token is valid
        manager = JWTCredentialsManagerFactory.new(self.store)
        brl_user_test = manager.get_user(token_1)
        self.assertEqual(brl_user, brl_user_test)
        sleep(0.1)  # Sleep a moment and change the password

        # Now change password and re-check old token
        self.user_service.change_password(self.brl_user, self.plain_password,
                                          "Newp@sW0rd")

        # Check the token is invalid (can't authenticate)
        self.assertRaises(DecodeError, manager.get_user, token_1)
Example #7
0
    def confirm_password_reset(self, confirmation_token):
        '''
        Confirms password change. User and password are inside the token
        '''
        try:
            # Decode token
            jwt_manager = JWTPasswordResetManagerFactory.new()
            brl_user, plain_password = jwt_manager.get_user_and_password(confirmation_token)
            user = self.store.read_user(brl_user)
        except Exception:
            raise NotFoundException("No user found with name %s" % brl_user)
        # Update password
        user.password = plain_password
        user.active = True  # If not active, activate now, email is validated
        self.store.update_user(user)

        # Generate an auth token to autologin user
        jwt_auth_manager = JWTCredentialsManagerFactory.new(self.store)
        token = jwt_auth_manager.get_token_for(brl_user)
        return token, brl_user
Example #8
0
    def install_plugins(self):
        self.bsonplugin = BSONBottlePlugin()
        # BiiResponse plugin. All rest methods has to return
        # (data serializable | None, biiresponse) or throw BiiServiceException subclass
        logger.info("Installing BiiReturnHandlerPlugin plugin...")
        self.biiresponseplugin = BiiReturnHandlerPlugin(self.bsonplugin)
        self.install(self.biiresponseplugin)

        # Very first of all, check SSL or die
        if BII_SSL_ENABLED:  # In heroku true for all environments
            logger.info("Installing NonSSLBlockerBottlePlugin plugin...")
            nonsslblock = NonSSLBlockerBottlePlugin()
            self.install(nonsslblock)

        # First of all, check DOS attacks by IP to the API
        # Counts IP request, raise 401 if banned

        if getattr(self.store, 'ip_mc_collection', False):
            logger.info("Installing massive DOS blocker...")
            doslogin = DOSBlockerBottlePlugin(self.store.ip_mc_collection,
                                              delta=BII_DOS_ATTACK_DELTA_TIME,
                                              max_events=BII_DOS_ATTACK_MAX_REQUEST,
                                              bantime=BII_DOS_ATTACK_BAN_TIME,
                                              callback_ip_banned=self.callback_ip_banned_for_DOS,
                                              banned_http_response=self.banned_http_response_for_DOS)
            # TODO: Maybe configure a log alert (heroku) if we return 401 banned
            # to analyze the case and adjust limits?
            self.install(doslogin)

        # Second, check Http Basic auth
        logger.info("Installing http basic authentication plugin...")
        httpplugin = HttpBasicAuthenticationBottlePlugin()
        self.install(httpplugin)

        # And check auth JWT
        logger.info("Installing JWT authentication plugin...")
        jwt_manager = JWTCredentialsManagerFactory.new(self.store)
        jwt_plugin = JWTAuthenticationBottlePlugin(jwt_manager)
        self.install(jwt_plugin)

        # Third check excess of login error for an IP
        # Catch generic 401 (or 404 or other) error from authentication and stores IP,
        # raise 401 if already banned
        if getattr(self.store, 'ip_mc_collection', False):
            logger.info("Installing massive error blocker...")
            massiveerrorplugin = MassiveErrorBlockerBottlePlugin(
                                   self.store.ip_mc_collection,
                                   delta=BII_ERROR_ATTACK_DELTA_TIME,
                                   max_events=BII_ERROR_ATTACK_MAX_ATTEMPTS,
                                   bantime=BII_ERROR_ATTACK_BAN_TIME,
                                   callback_ip_banned=self.callback_ip_banned_for_many_errors,
                                   banned_http_response=self.banned_http_response_for_many_errors)
            self.install(massiveerrorplugin)

        # Last, parse BSON data
        logger.info("Installing bson plugin...")
        self.install(self.bsonplugin)

        # Logging actions
        if BII_ENABLED_BII_USER_TRACE:
            self.tracebottleplugin = BiiUserTraceBottlePlugin()
            logger.info("Installing BiiUserTraceBottlePlugin plugin...")
            self.install(self.tracebottleplugin)