<commit_before>from org.jboss.seam.contexts import Context, Contexts
from org.jboss.seam.security import Identity
from javax.faces.context import FacesContext
from org.xdi.oxauth.service.python.interfaces import ExternalAuthenticatorType
from org.xdi.oxauth.service import UserService, ClientService, AuthenticationService, AttributeService
from org.xdi.util.security import StringEncrypter 
from org.xdi.util import StringHelper
from org.xdi.util import ArrayHelper
from java.util import Arrays, ArrayList, HashMap, IdentityHashMap
from org.xdi.oxauth.model.common import User, CustomAttribute
from org.xdi.oxauth.model.jwt import Jwt, JwtClaimName

import java

try:
    import json
except ImportError:
    import simplejson as json

class ExternalAuthenticator(ExternalAuthenticatorType):
    def __init__(self, currentTimeMillis):
        self.currentTimeMillis = currentTimeMillis
#+
    def init(self, configurationAttributes):
        print "Google+ initialization"

        if (not configurationAttributes.containsKey("gplus_client_secrets_file")):
            print "Google+ initialization. The property gplus_client_secrets_file is empty"
            return False
            
        gplus_client_secrets_file = configurationAttributes.get("gplus_client_secrets_file").getValue2()
        self.clientSecrets = self.loadClientSecrets(gplus_client_secrets_file)
        if (self.clientSecrets == None):
            print "Google+ initialization. File with Google+ client secrets should be not empty"
            return False

        self.attributesMapping = None
        if (configurationAttributes.containsKey("gplus_remote_attributes_list") and
            configurationAttributes.containsKey("gplus_local_attributes_list")):

            gplus_remote_attributes_list = configurationAttributes.get("gplus_remote_attributes_list").getValue2()
            if (StringHelper.isEmpty(gplus_remote_attributes_list)):
                print "Google+ initialization. The property gplus_remote_attributes_list is empty"
                return False

            gplus_local_attributes_list = configurationAttributes.get("gplus_local_attributes_list").getValue2()
            if (StringHelper.isEmpty(gplus_local_attributes_list)):
                print "Google+ initialization. The property gplus_local_attributes_list is empty"
                return False

            self.attributesMapping = self.prepareAttributesMapping(gplus_remote_attributes_list, gplus_local_attributes_list)
            if (self.attributesMapping == None):
                print "Google+ initialization. The attributes mapping isn't valid"
                return False

        self.extensionModule = None
        if (configurationAttributes.containsKey("extension_module")):
            extension_module_name = configurationAttributes.get("extension_module").getValue2()
            try:
                self.extensionModule = __import__(extension_module_name)
                gplus_extension_module_init_result = self.extensionModule.init(configurationAttributes)
                if (not gplus_extension_module_init_result):
                    return False
            except ImportError, ex:
                print "Failed to load gplus_extension_module:", extension_module_name
                print "Unexpected error:", ex
                return False

        print "Google+ initialized successfully"
        return True   

    def isValidAuthenticationMethod(self, usageType, configurationAttributes):
        return True

    def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):
        return None

    def authenticate(self, configurationAttributes, requestParameters, step):
        context = Contexts.getEventContext()
        authenticationService = AuthenticationService.instance()
        userService = UserService.instance()

        stringEncrypter = StringEncrypter.defaultInstance()

        gplus_map_user = False
        gplus_enroll_user = False
        # Use gplus_deployment_type only if there is no attributes mapping
        if (configurationAttributes.containsKey("gplus_deployment_type")):
            gplus_deployment_type = StringHelper.toLowerCase(configurationAttributes.get("gplus_deployment_type").getValue2())
            
            if (StringHelper.equalsIgnoreCase(gplus_deployment_type, "map")):
                gplus_map_user = True

            if (StringHelper.equalsIgnoreCase(gplus_deployment_type, "enroll")):
                gplus_enroll_user = True

        gplus_allow_basic_login = False
        if (configurationAttributes.containsKey("gplus_allow_basic_login")):
            gplus_allow_basic_login = StringHelper.toBoolean(configurationAttributes.get("gplus_allow_basic_login").getValue2(), False)

        use_basic_auth = False
        if (gplus_allow_basic_login):
            basic_auth = requestParameters.get("basic_auth")
            if (ArrayHelper.isNotEmpty(basic_auth)):
                use_basic_auth = StringHelper.toBoolean(basic_auth[0], False)

        if ((step == 1) and gplus_allow_basic_login and use_basic_auth):
            print "Google+ authenticate for step 1. Basic authentication"

            context.set("gplus_count_login_steps", 1)

            credentials = Identity.instance().getCredentials()
            user_name = credentials.getUsername()
            user_password = <PASSWORD>.<PASSWORD>()

            logged_in = False
            if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
                userService = UserService.instance()
                logged_in = userService.authenticate(user_name, user_password)

            if (not logged_in):
                return False

            return True

        if (step == 1):
            print "Google+ authenticate for step 1"

            currentClientSecrets = self.getCurrentClientSecrets(self.clientSecrets, configurationAttributes, requestParameters)
            if (currentClientSecrets == None):
                print "Google+ prepare for step 1. Client secrets configuration is invalid"
                return False
 
            gplus_auth_access_token_array = requestParameters.get("gplus_auth_access_token")
            if ArrayHelper.isEmpty(gplus_auth_access_token_array):
                print "Google+ authenticate for step 1. gplus_auth_access_token is empty"
                return False

            gplus_auth_access_token = gplus_auth_access_token_array[0]
            print "Google+ authenticate for step 1. gplus_response:", gplus_auth_access_token
 
            gplus_auth_id_token_array = requestParameters.get("gplus_auth_id_token")
            if ArrayHelper.isEmpty(gplus_auth_id_token_array):
                print "Google+ authenticate for step 1. gplus_auth_id_token is empty"
                return False

            gplus_auth_id_token = gplus_auth_id_token_array[0]
            print "Google+ authenticate for step 1. gplus_response:", gplus_auth_id_token
            
            jwt = Jwt.parse(gplus_auth_id_token)
            # TODO: Validate ID Token Signature  

            gplus_user_uid = jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER);
            print "Google+ authenticate for step 1. Found Google user ID in the ID token: ", gplus_user_uid
            
            if (gplus_map_user):
                # Use mapping to local IDP user
                print "Google+ authenticate for step 1. Attempting to find user by oxExternalUid: gplus:", gplus_user_uid

                # Check if the is user with specified gplus_user_uid
                find_user_by_uid = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplus_user_uid)

                if (find_user_by_uid == None):<commit_msg>Allow user to log using basic authentication method in Google+ auth module<commit_after>from org.jboss.seam.contexts import Context, Contexts
from org.jboss.seam.security import Identity
from javax.faces.context import FacesContext
from org.xdi.oxauth.service.python.interfaces import ExternalAuthenticatorType
from org.xdi.oxauth.service import UserService, ClientService, AuthenticationService, AttributeService
from org.xdi.util.security import StringEncrypter 
from org.xdi.util import StringHelper
from org.xdi.util import ArrayHelper
from java.util import Arrays, ArrayList, HashMap, IdentityHashMap
from org.xdi.oxauth.model.common import User, CustomAttribute
from org.xdi.oxauth.model.jwt import Jwt, JwtClaimName

import java

try:
    import json
except ImportError:
    import simplejson as json

class ExternalAuthenticator(ExternalAuthenticatorType):
    def __init__(self, currentTimeMillis):
        self.currentTimeMillis = currentTimeMillis
#+
    def init(self, configurationAttributes):
        print "Google+ initialization"

        if (not configurationAttributes.containsKey("gplus_client_secrets_file")):
            print "Google+ initialization. The property gplus_client_secrets_file is empty"
            return False
            
        gplus_client_secrets_file = configurationAttributes.get("gplus_client_secrets_file").getValue2()
        self.clientSecrets = self.loadClientSecrets(gplus_client_secrets_file)
        if (self.clientSecrets == None):
            print "Google+ initialization. File with Google+ client secrets should be not empty"
            return False

        self.attributesMapping = None
        if (configurationAttributes.containsKey("gplus_remote_attributes_list") and
            configurationAttributes.containsKey("gplus_local_attributes_list")):

            gplus_remote_attributes_list = configurationAttributes.get("gplus_remote_attributes_list").getValue2()
            if (StringHelper.isEmpty(gplus_remote_attributes_list)):
                print "Google+ initialization. The property gplus_remote_attributes_list is empty"
                return False

            gplus_local_attributes_list = configurationAttributes.get("gplus_local_attributes_list").getValue2()
            if (StringHelper.isEmpty(gplus_local_attributes_list)):
                print "Google+ initialization. The property gplus_local_attributes_list is empty"
                return False

            self.attributesMapping = self.prepareAttributesMapping(gplus_remote_attributes_list, gplus_local_attributes_list)
            if (self.attributesMapping == None):
                print "Google+ initialization. The attributes mapping isn't valid"
                return False

        self.extensionModule = None
        if (configurationAttributes.containsKey("extension_module")):
            extension_module_name = configurationAttributes.get("extension_module").getValue2()
            try:
                self.extensionModule = __import__(extension_module_name)
                gplus_extension_module_init_result = self.extensionModule.init(configurationAttributes)
                if (not gplus_extension_module_init_result):
                    return False
            except ImportError, ex:
                print "Failed to load gplus_extension_module:", extension_module_name
                print "Unexpected error:", ex
                return False

        print "Google+ initialized successfully"
        return True   

    def isValidAuthenticationMethod(self, usageType, configurationAttributes):
        return True

    def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):
        return None

    def authenticate(self, configurationAttributes, requestParameters, step):
        context = Contexts.getEventContext()
        authenticationService = AuthenticationService.instance()
        userService = UserService.instance()

        stringEncrypter = StringEncrypter.defaultInstance()

        gplus_map_user = False
        gplus_enroll_user = False
        # Use gplus_deployment_type only if there is no attributes mapping
        if (configurationAttributes.containsKey("gplus_deployment_type")):
            gplus_deployment_type = StringHelper.toLowerCase(configurationAttributes.get("gplus_deployment_type").getValue2())
            
            if (StringHelper.equalsIgnoreCase(gplus_deployment_type, "map")):
                gplus_map_user = True

            if (StringHelper.equalsIgnoreCase(gplus_deployment_type, "enroll")):
                gplus_enroll_user = True

        if (step == 1):
            print "Google+ authenticate for step 1"
 
            gplus_auth_access_token_array = requestParameters.get("gplus_auth_access_token")
            gplus_auth_access_token = gplus_auth_access_token_array[0]
 
            gplus_auth_id_token_array = requestParameters.get("gplus_auth_id_token")
            gplus_auth_id_token = gplus_auth_id_token_array[0]

            # Check if user uses basic method to log in
            use_basic_auth = False
            if (StringHelper.isEmptyString(gplus_auth_access_token) and StringHelper.isEmptyString(gplus_auth_id_token)):
                use_basic_auth = True

            # Use basic method to log in
            if (use_basic_auth):
                print "Google+ authenticate for step 1. Basic authentication"
        
                context.set("gplus_count_login_steps", 1)
        
                credentials = Identity.instance().getCredentials()
                user_name = credentials.getUsername()
                user_password = <PASSWORD>()
        
                logged_in = False
                if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
                    userService = UserService.instance()
                    logged_in = userService.authenticate(user_name, user_password)
        
                if (not logged_in):
                    return False
        
                return True

            # Use Google+ method to log in
            if StringHelper.isEmptyString(gplus_auth_access_token):
                print "Google+ authenticate for step 1. gplus_auth_access_token is empty"
                return False

            print "Google+ authenticate for step 1. gplus_response:", gplus_auth_access_token
 
            if StringHelper.isEmptyString(gplus_auth_id_token):
                print "Google+ authenticate for step 1. gplus_auth_id_token is empty"
                return False

            print "Google+ authenticate for step 1. gplus_response:", gplus_auth_id_token

            currentClientSecrets = self.getCurrentClientSecrets(self.clientSecrets, configurationAttributes, requestParameters)
            if (currentClientSecrets == None):
                print "Google+ prepare for step 1. Client secrets configuration is invalid"
                return False
            
            jwt = Jwt.parse(gplus_auth_id_token)
            # TODO: Validate ID Token Signature  

            gplus_user_uid = jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER);
            print "Google+ authenticate for step 1. Found Google user ID in the ID token: ", gplus_user_uid
            
            if (gplus_map_user):
                # Use mapping to local IDP user
                print "Google+ authenticate for step 1. Attempting to find user by oxExternalUid: gplus:", gplus_user_uid

                # Check if the is user with specified gplus_user_uid
                find_user_by_uid = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplus_user_uid)

                if (find_user_by_uid == None):
{'fraction_non_alphanumeric': 0.06409841372612496, 'fraction_numerical': 0.0025250890255746196, 'mean_word_length': 2.812885707232782, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2558728', 'n_tokens_mistral': 4012, 'n_tokens_neox': 3838, 'n_words': 914}