def test_synchronize_external_groups(self):
     """webgroup - synchronizing one user external groups"""
     from invenio.webgroup import synchronize_external_groups
     from invenio.webgroup_dblayer import get_external_groups
     synchronize_external_groups(self.uid, {
         'group1': 'descr1',
         'group2': 'descr2'
     }, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group2' in groups_names)
     synchronize_external_groups(self.uid, {
         'group1': 'descr1',
         'group2': 'descr2'
     }, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group2' in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {
         'group1': 'descr1',
         'group3': 'descr2'
     }, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group3' in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless(len(groups_names) == 0)
Пример #2
0
 def test_synchronize_external_groups(self):
     """webgroup - synchronizing one user external groups"""
     from invenio.webgroup import synchronize_external_groups
     from invenio.legacy.websession.dblayer import get_external_groups
     synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group2' in groups_names)
     synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group2' in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group3' : 'descr2'}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group3' in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless(len(groups_names) == 0)
 def test_synchronize_external_groups(self):
     """webgroup - synchronizing one user external groups"""
     synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group2' in groups_names)
     synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group2' in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group3' : 'descr2'}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless('group1' in groups_names)
     self.failUnless('group3' in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless(len(groups_names) == 0)
 def test_synchronize_external_groups(self):
     """webgroup - synchronizing one user external groups"""
     synchronize_external_groups(self.uid, {"group1": "descr1", "group2": "descr2"}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless("group1" in groups_names)
     self.failUnless("group2" in groups_names)
     synchronize_external_groups(self.uid, {"group1": "descr1", "group2": "descr2"}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless("group1" in groups_names)
     self.failUnless("group2" in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {"group1": "descr1", "group3": "descr2"}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless("group1" in groups_names)
     self.failUnless("group3" in groups_names)
     self.failUnless(len(groups_names) == 2)
     synchronize_external_groups(self.uid, {}, self.login_method)
     groups = get_external_groups(self.uid)
     groups_names = [name[1] for name in groups]
     self.failUnless(len(groups_names) == 0)
Пример #5
0
def loginUser(req, p_un, p_pw, login_method):
    """It is a first simple version for the authentication of user. It returns the id of the user,
       for checking afterwards if the login is correct
    """

    # p_un passed may be an email or a nickname:
    p_email = get_email_from_username(p_un)

    # go on with the old stuff based on p_email:

    if not login_method in CFG_EXTERNAL_AUTHENTICATION:
        return ([], p_email, p_pw, 12)

    if CFG_EXTERNAL_AUTHENTICATION[login_method]: # External Authenthication
        try:
            p_email = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_email, p_pw, req) or CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_un, p_pw, req) ## We try to login with either the email of the nickname
            if p_email:
                p_email = p_email.lower()
            else:
                return([], p_email, p_pw, 15)
        except InvenioWebAccessExternalAuthError:
            register_exception(req=req, alert_admin=True)
            raise
        if p_email: # Authenthicated externally
            query_result = run_sql("SELECT id from user where email=%s", (p_email,))
            if not query_result: # First time user
                p_pw_local = int(random.random() * 1000000)
                p_nickname = ''
                if CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames:
                    try: # Let's discover the external nickname!
                        p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req)
                    except (AttributeError, NotImplementedError):
                        pass
                    except:
                        register_exception(req=req, alert_admin=True)
                        raise
                res = registerUser(req, p_email, p_pw_local, p_nickname,
                        register_without_nickname=p_nickname == '',
                        login_method=login_method)
                if res == 4 or res == 2: # The nickname was already taken
                    res = registerUser(req, p_email, p_pw_local, '',
                    register_without_nickname=True,
                    login_method=login_method)
                    query_result = run_sql("SELECT id from user where email=%s", (p_email,))
                elif res == 0: # Everything was ok, with or without nickname.
                    query_result = run_sql("SELECT id from user where email=%s", (p_email,))
                elif res == 6: # error in contacting the user via email
                    return([], p_email, p_pw_local, 19)
                else:
                    return([], p_email, p_pw_local, 13)
            elif CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames:
                ## Let's still fetch a possibly upgraded nickname.
                try: # Let's discover the external nickname!
                    p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req)
                    if nickname_valid_p(p_nickname) and nicknameUnique(p_nickname) == 0:
                        updateDataUser(query_result[0][0], p_email, p_nickname)
                except (AttributeError, NotImplementedError):
                    pass
                except:
                    register_exception(alert_admin=True)
                    raise
            try:
                groups = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_groups_membership(p_email, p_pw, req)
                # groups is a dictionary {group_name : group_description,}
                new_groups = {}
                for key, value in groups.items():
                    new_groups[key + " [" + str(login_method) + "]"] = value
                groups = new_groups
            except (AttributeError, NotImplementedError):
                pass
            except:
                register_exception(req=req, alert_admin=True)
                return([], p_email, p_pw, 16)
            else: # Groups synchronization
                if groups:
                    userid = query_result[0][0]
                    from invenio.webgroup import synchronize_external_groups
                    synchronize_external_groups(userid, groups, login_method)

            user_prefs = get_user_preferences(query_result[0][0])
            if not CFG_EXTERNAL_AUTHENTICATION[login_method]:
                ## I.e. if the login method is not of robot type:
                if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4:
                    # Let's prevent the user to switch login_method
                    if user_prefs.has_key("login_method") and \
                            user_prefs["login_method"] != login_method:
                        return([], p_email, p_pw, 11)
                user_prefs["login_method"] = login_method

            # Cleaning external settings
            for key in user_prefs.keys():
                if key.startswith('EXTERNAL_'):
                    del user_prefs[key]
            try:
                # Importing external settings
                new_prefs = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_preferences(p_email, p_pw, req)
                for key, value in new_prefs.items():
                    user_prefs['EXTERNAL_' + key] = value
            except (AttributeError, NotImplementedError):
                pass
            except InvenioWebAccessExternalAuthError:
                register_exception(req=req, alert_admin=True)
                return([], p_email, p_pw, 16)
            # Storing settings
            set_user_preferences(query_result[0][0], user_prefs)
        else:
            return ([], p_un, p_pw, 10)
    else: # Internal Authenthication
        if not p_pw:
            p_pw = ''
        query_result = run_sql("SELECT id,email,note from user where email=%s and password=AES_ENCRYPT(email,%s)", (p_email, p_pw,))
        if query_result:
            #FIXME drop external groups and settings
            note = query_result[0][2]
            if note == '1': # Good account
                preferred_login_method = get_user_preferences(query_result[0][0])['login_method']
                p_email = query_result[0][1].lower()
                if login_method != preferred_login_method:
                    if preferred_login_method in CFG_EXTERNAL_AUTHENTICATION:
                        return ([], p_email, p_pw, 11)
            elif note == '2': # Email address need to be confirmed by user
                return ([], p_email, p_pw, 17)
            elif note == '0': # Account need to be confirmed by administrator
                return ([], p_email, p_pw, 18)
        else:
            return ([], p_email, p_pw, 14)
    # Login successful! Updating the last access time
    run_sql("UPDATE user SET last_login=NOW() WHERE email=%s", (p_email,))
    return (query_result, p_email, p_pw, 0)
Пример #6
0
def collect_user_info(req, login_time=False, refresh=False):
    """Given the mod_python request object rec or a uid it returns a dictionary
    containing at least the keys uid, nickname, email, groups, plus any external keys in
    the user preferences (collected at login time and built by the different
    external authentication plugins) and if the mod_python request object is
    provided, also the remote_ip, remote_host, referer, agent fields.
    NOTE: if req is a mod_python request object, the user_info dictionary
    is saved into req._user_info (for caching purpouses)
    setApacheUser & setUid will properly reset it.
    """
    from invenio.search_engine import get_permitted_restricted_collections
    user_info = {
        'remote_ip' : '',
        'remote_host' : '',
        'referer' : '',
        'uri' : '',
        'agent' : '',
        'uid' :-1,
        'nickname' : '',
        'email' : '',
        'group' : [],
        'guest' : '1',
        'session' : None,
        'precached_permitted_restricted_collections' : [],
        'precached_usebaskets' : False,
        'precached_useloans' : False,
        'precached_usegroups' : False,
        'precached_usealerts' : False,
        'precached_usemessages' : False,
        'precached_viewsubmissions' : False,
        'precached_useapprove' : False,
        'precached_useadmin' : False,
        'precached_usestats' : False,
        'precached_viewclaimlink' : False,
        'precached_usepaperclaim' : False,
        'precached_usepaperattribution' : False,
    }

    try:
        is_req = False
        if not req:
            uid = -1
        elif type(req) in (type(1), type(1L)):
            ## req is infact a user identification
            uid = req
        elif type(req) is dict:
            ## req is by mistake already a user_info
            try:
                assert(req.has_key('uid'))
                assert(req.has_key('email'))
                assert(req.has_key('nickname'))
            except AssertionError:
                ## mmh... misuse of collect_user_info. Better warn the admin!
                register_exception(alert_admin=True)
            user_info.update(req)
            return user_info
        else:
            is_req = True
            uid = getUid(req)
            if hasattr(req, '_user_info') and not login_time:
                user_info = req._user_info
                if not refresh:
                    return req._user_info
            req._user_info = user_info
            try:
                user_info['remote_ip'] = req.remote_ip
            except gaierror:
                #FIXME: we should support IPV6 too. (hint for FireRole)
                pass
            user_info['session'] = get_session(req).sid()
            user_info['remote_host'] = req.remote_host or ''
            user_info['referer'] = req.headers_in.get('Referer', '')
            user_info['uri'] = req.unparsed_uri or ()
            user_info['agent'] = req.headers_in.get('User-Agent', 'N/A')
        user_info['uid'] = uid
        user_info['nickname'] = get_nickname(uid) or ''
        user_info['email'] = get_email(uid) or ''
        user_info['group'] = []
        user_info['guest'] = str(isGuestUser(uid))

        if user_info['guest'] == '1' and CFG_INSPIRE_SITE:
            usepaperattribution = False
            viewclaimlink = False

            if (CFG_BIBAUTHORID_ENABLED
                and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionviewers"))):
                usepaperattribution = True

#            if (CFG_BIBAUTHORID_ENABLED
#                and usepaperattribution
#                and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionlinkviewers"))):
#                viewclaimlink = True
            if is_req:
                session = get_session(req)
                viewlink = False
                try:
                    viewlink = session['personinfo']['claim_in_process']
                except (KeyError, TypeError):
                    viewlink = False
            else:
                viewlink = False

            if (CFG_BIBAUTHORID_ENABLED
                and usepaperattribution
                and viewlink):
                    viewclaimlink = True

            user_info['precached_viewclaimlink'] = viewclaimlink
            user_info['precached_usepaperattribution'] = usepaperattribution

        if user_info['guest'] == '0':
            user_info['group'] = [group[1] for group in get_groups(uid)]
            prefs = get_user_preferences(uid)
            login_method = prefs['login_method']
            login_object = CFG_EXTERNAL_AUTHENTICATION[login_method]
            if login_object and ((datetime.datetime.now() - get_last_login(uid)).seconds > 3600):
                ## The user uses an external authentication method and it's a bit since
                ## she has not performed a login
                if not CFG_EXTERNAL_AUTH_USING_SSO or (
                    is_req and login_object.in_shibboleth(req)):
                    ## If we're using SSO we must be sure to be in HTTPS and Shibboleth handler
                    ## otherwise we can't really read anything, hence
                    ## it's better skip the synchronization
                    try:
                        groups = login_object.fetch_user_groups_membership(user_info['email'], req=req)
                        # groups is a dictionary {group_name : group_description,}
                        new_groups = {}
                        for key, value in groups.items():
                            new_groups[key + " [" + str(login_method) + "]"] = value
                        groups = new_groups
                    except (AttributeError, NotImplementedError, TypeError, InvenioWebAccessExternalAuthError):
                        pass
                    else: # Groups synchronization
                        from invenio.webgroup import synchronize_external_groups
                        synchronize_external_groups(uid, groups, login_method)
                        user_info['group'] = [group[1] for group in get_groups(uid)]

                    try:
                        # Importing external settings
                        new_prefs = login_object.fetch_user_preferences(user_info['email'], req=req)
                        for key, value in new_prefs.items():
                            prefs['EXTERNAL_' + key] = value
                    except (AttributeError, NotImplementedError, TypeError, InvenioWebAccessExternalAuthError):
                        pass
                    else:
                        set_user_preferences(uid, prefs)
                        prefs = get_user_preferences(uid)

                    run_sql('UPDATE user SET last_login=NOW() WHERE id=%s', (uid,))
            if prefs:
                for key, value in prefs.iteritems():
                    user_info[key.lower()] = value
            if login_time:
                ## Heavy computational information
                from invenio.access_control_engine import acc_authorize_action
                if CFG_WEBSEARCH_PERMITTED_RESTRICTED_COLLECTIONS_LEVEL > 0:
                    user_info['precached_permitted_restricted_collections'] = get_permitted_restricted_collections(user_info)
                user_info['precached_usebaskets'] = acc_authorize_action(user_info, 'usebaskets')[0] == 0
                user_info['precached_useloans'] = acc_authorize_action(user_info, 'useloans')[0] == 0
                user_info['precached_usegroups'] = acc_authorize_action(user_info, 'usegroups')[0] == 0
                user_info['precached_usealerts'] = acc_authorize_action(user_info, 'usealerts')[0] == 0
                user_info['precached_usemessages'] = acc_authorize_action(user_info, 'usemessages')[0] == 0
                user_info['precached_usestats'] = acc_authorize_action(user_info, 'runwebstatadmin')[0] == 0
                user_info['precached_viewsubmissions'] = isUserSubmitter(user_info)
                user_info['precached_useapprove'] = isUserReferee(user_info)
                user_info['precached_useadmin'] = isUserAdmin(user_info)
                usepaperclaim = False
                usepaperattribution = False
                viewclaimlink = False

                if (CFG_BIBAUTHORID_ENABLED
                    and acc_is_user_in_role(user_info, acc_get_role_id("paperclaimviewers"))):
                    usepaperclaim = True

                if (CFG_BIBAUTHORID_ENABLED
                    and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionviewers"))):
                    usepaperattribution = True

                if is_req:
                    session = get_session(req)
                    viewlink = False
                    try:
                        viewlink = session['personinfo']['claim_in_process']
                    except (KeyError, TypeError):
                        viewlink = False
                else:
                    viewlink = False

                if (CFG_BIBAUTHORID_ENABLED
                    and usepaperattribution
                    and viewlink):
                        viewclaimlink = True

#                if (CFG_BIBAUTHORID_ENABLED
#                    and ((usepaperclaim or usepaperattribution)
#                         and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionlinkviewers")))):
#                    viewclaimlink = True

                user_info['precached_viewclaimlink'] = viewclaimlink
                user_info['precached_usepaperclaim'] = usepaperclaim
                user_info['precached_usepaperattribution'] = usepaperattribution

    except Exception, e:
        register_exception()
Пример #7
0
def loginUser(req, p_un, p_pw, login_method):
    """It is a first simple version for the authentication of user. It returns the id of the user,
       for checking afterwards if the login is correct
    """

    # p_un passed may be an email or a nickname:
    p_email = get_email_from_username(p_un)

    # go on with the old stuff based on p_email:

    if not login_method in CFG_EXTERNAL_AUTHENTICATION:
        return (None, p_email, p_pw, 12)

    if CFG_EXTERNAL_AUTHENTICATION[login_method]: # External Authentication
        try:
            result = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_email, p_pw, req)
            if (result == (None, None) or result is None) and not login_method in ['oauth1', 'oauth2', 'openid']:
                # There is no need to call auth_user with username for
                # OAuth1, OAuth2 and OpenID authentication
                result = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_un, p_pw, req) ## We try to login with either the email of the nickname
            if isinstance(result, (tuple, list)) and len(result) == 2:
                p_email, p_extid = result
            else:
                ## For backward compatibility we use the email as external
                ## identifier if it was not returned already by the plugin
                p_email, p_extid = str(result), str(result)

            if p_email:
                p_email = p_email.lower()
                if not p_extid:
                    p_extid = p_email
            elif not p_extid:
                try:
                    # OpenID and OAuth authentications have own error messages
                    return (None, p_email, p_pw, CFG_EXTERNAL_AUTHENTICATION[login_method].get_msg(req))
                except NotImplementedError:
                    return(None, p_email, p_pw, 15)
            else:
                # External login is successfull but couldn't fetch the email
                # address.
                generate_string = lambda: reduce((lambda x, y: x+y), [random.choice("qwertyuiopasdfghjklzxcvbnm1234567890") for i in range(32)])
                random_string = generate_string()
                p_email = CFG_TEMP_EMAIL_ADDRESS % random_string
                while run_sql("SELECT * FROM user WHERE email=%s", (p_email,)):
                    random_string = generate_string()
                    p_email = CFG_TEMP_EMAIL_ADDRESS % random_string

        except InvenioWebAccessExternalAuthError:
            register_exception(req=req, alert_admin=True)
            raise
        if p_email: # Authenthicated externally
            query_result = run_sql("SELECT id_user FROM userEXT WHERE id=%s and method=%s", (p_extid, login_method))
            if query_result:
                ## User was already registered with this external method.
                id_user = query_result[0][0]
                old_email = run_sql("SELECT email FROM user WHERE id=%s", (id_user,))[0][0]

                # Look if the email address matches with the template given.
                # If it matches, use the email address saved in the database.
                regexp = re.compile(CFG_TEMP_EMAIL_ADDRESS % r"\w*")
                if regexp.match(p_email):
                    p_email = old_email

                if old_email != p_email:
                    ## User has changed email of reference.
                    res = run_sql("SELECT id FROM user WHERE email=%s", (p_email,))
                    if res:
                        ## User was also registered with the other email.
                        ## We should merge the two!
                        new_id = res[0][0]
                        if new_id == id_user:
                            raise AssertionError("We should not reach this situation: new_id=%s, id_user=%s, old_email=%s, p_email=%s" % (new_id, id_user, old_email, p_email))
                        merge_usera_into_userb(id_user, new_id)
                        run_sql("DELETE FROM user WHERE id=%s", (id_user, ))
                        for row in run_sql("SELECT method FROM userEXT WHERE id_user=%s", (id_user, )):
                            ## For all known accounts of id_user not conflicting with new_id we move them to refer to new_id
                            if not run_sql("SELECT method FROM userEXT WHERE id_user=%s AND method=%s", (new_id, row[0])):
                                run_sql("UPDATE userEXT SET id_user=%s WHERE id_user=%s AND method=%s", (new_id, id_user, row[0]))
                        ## And we delete the duplicate remaining ones :-)
                        run_sql("DELETE FROM userEXT WHERE id_user=%s", (id_user, ))
                        id_user = new_id
                    else:
                        ## We just need to rename the email address of the
                        ## corresponding user. Unfortunately the local
                        ## password will be then invalid, but its unlikely
                        ## the user is using both an external and a local
                        ## account.
                        run_sql("UPDATE user SET email=%s WHERE id=%s", (p_email, id_user))
            else:
                ## User was not already registered with this external method.
                query_result = run_sql("SELECT id FROM user WHERE email=%s", (p_email, ))
                if query_result:
                    ## The user was already known with this email
                    id_user = query_result[0][0]
                    ## We fix the inconsistence in the userEXT table.
                    run_sql("INSERT INTO userEXT(id, method, id_user) VALUES(%s, %s, %s) ON DUPLICATE KEY UPDATE id=%s, method=%s, id_user=%s", (p_extid, login_method, id_user, p_extid, login_method, id_user))
                else:
                    ## First time user
                    p_pw_local = int(random.random() * 1000000)
                    p_nickname = ''
                    if CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames:
                        try: # Let's discover the external nickname!
                            p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req)
                        except (AttributeError, NotImplementedError):
                            pass
                        except:
                            register_exception(req=req, alert_admin=True)
                            raise
                    res = registerUser(req, p_email, p_pw_local, p_nickname,
                            register_without_nickname=p_nickname == '',
                            login_method=login_method)
                    if res == 4 or res == 2: # The nickname was already taken
                        res = registerUser(req, p_email, p_pw_local, '',
                        register_without_nickname=True,
                        login_method=login_method)
                        query_result = run_sql("SELECT id from user where email=%s", (p_email,))
                        id_user = query_result[0][0]
                    elif res == 0: # Everything was ok, with or without nickname.
                        query_result = run_sql("SELECT id from user where email=%s", (p_email,))
                        id_user = query_result[0][0]
                    elif res == 6: # error in contacting the user via email
                        return (None, p_email, p_pw_local, 19)
                    else:
                        return (None, p_email, p_pw_local, 13)
                    run_sql("INSERT INTO userEXT(id, method, id_user) VALUES(%s, %s, %s)", (p_extid, login_method, id_user))
            if CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames:
                ## Let's still fetch a possibly upgraded nickname.
                try: # Let's discover the external nickname!
                    p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req)
                    if nickname_valid_p(p_nickname) and nicknameUnique(p_nickname) == 0:
                        updateDataUser(id_user, p_email, p_nickname)
                except (AttributeError, NotImplementedError):
                    pass
                except:
                    register_exception(alert_admin=True)
                    raise
            try:
                groups = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_groups_membership(p_email, p_pw, req)
                # groups is a dictionary {group_name : group_description,}
                new_groups = {}
                for key, value in groups.items():
                    new_groups[key + " [" + str(login_method) + "]"] = value
                groups = new_groups
            except (AttributeError, NotImplementedError):
                pass
            except:
                register_exception(req=req, alert_admin=True)
                return (None, p_email, p_pw, 16)
            else: # Groups synchronization
                if groups:
                    from invenio.webgroup import synchronize_external_groups
                    synchronize_external_groups(id_user, groups, login_method)

            user_prefs = get_user_preferences(id_user)
            if not CFG_EXTERNAL_AUTHENTICATION[login_method]:
                ## I.e. if the login method is not of robot type:
                if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4:
                    # Let's prevent the user to switch login_method
                    if "login_method" in user_prefs and \
                            user_prefs["login_method"] != login_method:
                        return (None, p_email, p_pw, 11)
                user_prefs["login_method"] = login_method

            # Cleaning external settings
            for key in user_prefs.keys():
                if key.startswith('EXTERNAL_'):
                    del user_prefs[key]
            try:
                # Importing external settings
                new_prefs = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_preferences(p_email, p_pw, req)
                for key, value in new_prefs.items():
                    user_prefs['EXTERNAL_' + key] = value
            except (AttributeError, NotImplementedError):
                pass
            except InvenioWebAccessExternalAuthError:
                register_exception(req=req, alert_admin=True)
                return (None, p_email, p_pw, 16)
            # Storing settings
            set_user_preferences(id_user, user_prefs)
        else:
            return (None, p_un, p_pw, 10)
    else: # Internal Authenthication
        if not p_pw:
            p_pw = ''
        query_result = run_sql("SELECT id,email,note from user where email=%s and password=AES_ENCRYPT(email,%s)", (p_email, p_pw,))
        if query_result:
            #FIXME drop external groups and settings
            note = query_result[0][2]
            id_user = query_result[0][0]
            if note == '1': # Good account
                preferred_login_method = get_user_preferences(query_result[0][0])['login_method']
                p_email = query_result[0][1].lower()
                if login_method != preferred_login_method:
                    if preferred_login_method in CFG_EXTERNAL_AUTHENTICATION:
                        return (None, p_email, p_pw, 11)
            elif note == '2': # Email address need to be confirmed by user
                return (None, p_email, p_pw, 17)
            elif note == '0': # Account need to be confirmed by administrator
                return (None, p_email, p_pw, 18)
        else:
            return (None, p_email, p_pw, 14)
    # Login successful! Updating the last access time
    run_sql("UPDATE user SET last_login=NOW() WHERE email=%s", (p_email,))
    return (id_user, p_email, p_pw, 0)
Пример #8
0
def loginUser(req, p_un, p_pw, login_method):
    """It is a first simple version for the authentication of user. It returns the id of the user,
       for checking afterwards if the login is correct
    """

    # p_un passed may be an email or a nickname:
    p_email = get_email_from_username(p_un)

    # go on with the old stuff based on p_email:

    if not login_method in CFG_EXTERNAL_AUTHENTICATION:
        return ([], p_email, p_pw, 12)

    if CFG_EXTERNAL_AUTHENTICATION[login_method]:  # External Authenthication
        try:
            p_email = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(
                p_email, p_pw,
                req) or CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(
                    p_un, p_pw, req
                )  ## We try to login with either the email of the nickname
            if p_email:
                p_email = p_email.lower()
            else:
                return ([], p_email, p_pw, 15)
        except InvenioWebAccessExternalAuthError:
            register_exception(req=req, alert_admin=True)
            raise
        if p_email:  # Authenthicated externally
            query_result = run_sql("SELECT id from user where email=%s",
                                   (p_email, ))
            if not query_result:  # First time user
                p_pw_local = int(random.random() * 1000000)
                p_nickname = ''
                if CFG_EXTERNAL_AUTHENTICATION[
                        login_method].enforce_external_nicknames:
                    try:  # Let's discover the external nickname!
                        p_nickname = CFG_EXTERNAL_AUTHENTICATION[
                            login_method].fetch_user_nickname(
                                p_email, p_pw, req)
                    except (AttributeError, NotImplementedError):
                        pass
                    except:
                        register_exception(req=req, alert_admin=True)
                        raise
                res = registerUser(req,
                                   p_email,
                                   p_pw_local,
                                   p_nickname,
                                   register_without_nickname=p_nickname == '',
                                   login_method=login_method)
                if res == 4 or res == 2:  # The nickname was already taken
                    res = registerUser(req,
                                       p_email,
                                       p_pw_local,
                                       '',
                                       register_without_nickname=True,
                                       login_method=login_method)
                    query_result = run_sql(
                        "SELECT id from user where email=%s", (p_email, ))
                elif res == 0:  # Everything was ok, with or without nickname.
                    query_result = run_sql(
                        "SELECT id from user where email=%s", (p_email, ))
                elif res == 6:  # error in contacting the user via email
                    return ([], p_email, p_pw_local, 19)
                else:
                    return ([], p_email, p_pw_local, 13)
            try:
                groups = CFG_EXTERNAL_AUTHENTICATION[
                    login_method].fetch_user_groups_membership(
                        p_email, p_pw, req)
                # groups is a dictionary {group_name : group_description,}
                new_groups = {}
                for key, value in groups.items():
                    new_groups[key + " [" + str(login_method) + "]"] = value
                groups = new_groups
            except (AttributeError, NotImplementedError):
                pass
            except:
                register_exception(req=req, alert_admin=True)
                return ([], p_email, p_pw, 16)
            else:  # Groups synchronization
                if groups:
                    userid = query_result[0][0]
                    from invenio.webgroup import synchronize_external_groups
                    synchronize_external_groups(userid, groups, login_method)

            user_prefs = get_user_preferences(query_result[0][0])
            if not CFG_EXTERNAL_AUTHENTICATION[login_method]:
                ## I.e. if the login method is not of robot type:
                if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4:
                    # Let's prevent the user to switch login_method
                    if user_prefs.has_key("login_method") and \
                            user_prefs["login_method"] != login_method:
                        return ([], p_email, p_pw, 11)
                user_prefs["login_method"] = login_method

            # Cleaning external settings
            for key in user_prefs.keys():
                if key.startswith('EXTERNAL_'):
                    del user_prefs[key]
            try:
                # Importing external settings
                new_prefs = CFG_EXTERNAL_AUTHENTICATION[
                    login_method].fetch_user_preferences(p_email, p_pw, req)
                for key, value in new_prefs.items():
                    user_prefs['EXTERNAL_' + key] = value
            except (AttributeError, NotImplementedError):
                pass
            except InvenioWebAccessExternalAuthError:
                register_exception(req=req, alert_admin=True)
                return ([], p_email, p_pw, 16)
            # Storing settings
            set_user_preferences(query_result[0][0], user_prefs)
        else:
            return ([], p_un, p_pw, 10)
    else:  # Internal Authenthication
        if not p_pw:
            p_pw = ''
        query_result = run_sql(
            "SELECT id,email,note from user where email=%s and password=AES_ENCRYPT(email,%s)",
            (
                p_email,
                p_pw,
            ))
        if query_result:
            #FIXME drop external groups and settings
            note = query_result[0][2]
            if note == '1':  # Good account
                preferred_login_method = get_user_preferences(
                    query_result[0][0])['login_method']
                p_email = query_result[0][1].lower()
                if login_method != preferred_login_method:
                    if preferred_login_method in CFG_EXTERNAL_AUTHENTICATION:
                        return ([], p_email, p_pw, 11)
            elif note == '2':  # Email address need to be confirmed by user
                return ([], p_email, p_pw, 17)
            elif note == '0':  # Account need to be confirmed by administrator
                return ([], p_email, p_pw, 18)
        else:
            return ([], p_email, p_pw, 14)
    # Login successful! Updating the last access time
    run_sql("UPDATE user SET last_login=NOW() WHERE email=%s", (p_email, ))
    return (query_result, p_email, p_pw, 0)
Пример #9
0
                    ## it's better skeep the synchronization
                    try:
                        groups = login_object.fetch_user_groups_membership(
                            user_info['email'], req=req)
                        # groups is a dictionary {group_name : group_description,}
                        new_groups = {}
                        for key, value in groups.items():
                            new_groups[key + " [" + str(login_method) +
                                       "]"] = value
                        groups = new_groups
                    except (AttributeError, NotImplementedError, TypeError,
                            InvenioWebAccessExternalAuthError):
                        pass
                    else:  # Groups synchronization
                        from invenio.webgroup import synchronize_external_groups
                        synchronize_external_groups(uid, groups, login_method)
                        user_info['group'] = [
                            group[1] for group in get_groups(uid)
                        ]

                    try:
                        # Importing external settings
                        new_prefs = login_object.fetch_user_preferences(
                            user_info['email'], req=req)
                        for key, value in new_prefs.items():
                            prefs['EXTERNAL_' + key] = value
                    except (AttributeError, NotImplementedError, TypeError,
                            InvenioWebAccessExternalAuthError):
                        pass
                    else:
                        set_user_preferences(uid, prefs)