def fetch_user_nickname(self, username, password=None, req=None):
     """Given a username and a password, returns the right nickname belonging
     to that user (username could be an email).
     """
     if self.nickname_attribute_name:
         data = self.__extract_attribute(req)
         nickname = data.get(self.nickname_attribute_name)
         if nickname:
             if isinstance(nickname, str):
                 return nickname.strip().lower()
             else:
                 raise InvenioWebAccessExternalAuthError("The nickname provided in the assertion is invalid: %s" % (repr(nickname)))
     return None
 def fetch_user_groups_membership(self, username, password=None, req=None):
     """Given a username and a password, returns a dictionary of groups
     and their description to which the user is subscribed.
     Raise InvenioWebAccessExternalAuthError in case of troubles.
     """
     if self.groups_attribute_name:
         data = self.__extract_attribute(req)
         groups = data.get(self.groups_attribute_name)
         if groups:
             if isinstance(groups, str):
                 groups = [group.strip() for group in groups.split(self.groups_separator)]
                 return dict(zip(groups, groups))
             else:
                 raise InvenioWebAccessExternalAuthError("The groups provided in the assertion are invalid: %s" % (repr(groups)))
     return {}
 def __extract_attribute(self, req):
     """
     Load from the request the given assertion, extract all the attribute
     to properly login the user, and verify that the data are actually
     both well formed and signed correctly.
     """
     from invenio.webinterface_handler import wash_urlargd
     args = wash_urlargd(
         req.form, {
             'assertion': (str, ''),
             'robot': (str, ''),
             'digest': (str, ''),
             'login_method': (str, '')
         })
     assertion = args['assertion']
     digest = args['digest']
     robot = args['robot']
     login_method = args['login_method']
     shared_key = load_robot_keys().get(login_method, {}).get(robot)
     if shared_key is None:
         raise InvenioWebAccessExternalAuthError(
             "A key does not exist for robot: %s, login_method: %s" %
             (robot, login_method))
     if not self.verify(shared_key, assertion, digest):
         raise InvenioWebAccessExternalAuthError(
             "The provided assertion does not validate against the digest %s for robot %s"
             % (repr(digest), repr(robot)))
     if self.use_zlib:
         try:
             ## Workaround to Perl implementation that does not add
             ## any padding to the base64 encoding.
             needed_pad = (4 - len(assertion) % 4) % 4
             assertion += needed_pad * '='
             assertion = decompress(base64.urlsafe_b64decode(assertion))
         except:
             raise InvenioWebAccessExternalAuthError(
                 "The provided assertion is corrupted")
     data = json_unicode_to_utf8(json.loads(assertion))
     if not isinstance(data, dict):
         raise InvenioWebAccessExternalAuthError(
             "The provided assertion is invalid")
     timeout = data[self.timeout_attribute_name]
     if timeout < time.time():
         raise InvenioWebAccessExternalAuthError(
             "The provided assertion is expired")
     userip = data.get(self.userip_attribute_name)
     if not self.check_user_ip or (normalize_ip(
             userip, self.check_user_ip) == normalize_ip(
                 req.remote_ip, self.check_user_ip)):
         return data
     else:
         raise InvenioWebAccessExternalAuthError(
             "The provided assertion has been issued for a different IP address (%s instead of %s)"
             % (userip, req.remote_ip))
 def auth_user(self, username, password, req=None):
     """Authenticate user-supplied USERNAME and PASSWORD.  Return
     None if authentication failed, or the email address of the
     person if the authentication was successful.  In order to do
     this you may perhaps have to keep a translation table between
     usernames and email addresses.
     Raise InvenioWebAccessExternalAuthError in case of external troubles.
     """
     data = self.__extract_attribute(req)
     email = data.get(self.email_attribute_name)
     if email:
         if isinstance(email, str):
             return email.strip().lower()
         else:
             raise InvenioWebAccessExternalAuthError("The email provided in the assertion is invalid: %s" % (repr(email)))
     else:
         return None