diff --git a/gauth_login/gauth_login.module b/gauth_login/gauth_login.module index e488c29..bfbc0b5 100755 --- a/gauth_login/gauth_login.module +++ b/gauth_login/gauth_login.module @@ -41,110 +41,135 @@ function gauth_login_menu() { */ function gauth_login_gauth_google_response() { if (isset($_GET['state'])) { - $state = json_decode($_GET['state'], TRUE); - if (isset($state['src']) && $state['src'] != 'gauth_login') { - // Handle response only if the request was from gauth_login. - return; - } - if ($state['hash'] != $_SESSION['gauth_login_state']['hash']) { - drupal_set_message(t('Invalid state parameter'), 'error'); - drupal_access_denied(); - return; - } - $redirect_url = isset($state['destination']) ? $state['destination'] : ''; + $state = json_decode($_GET['state'], TRUE); + checkStateSource($state); + validateStateParameter($state); + if (isset($_GET['code'])) { - $client_id = variable_get('gauth_login_client_id'); - $client_secret = variable_get('gauth_login_client_secret'); - $api_key = variable_get('gauth_login_developer_key'); - $client = new Google_Client(); - $client->setApplicationName("Google OAuth2"); - $client->setClientId($client_id); - $client->setClientSecret($client_secret); - $client->setRedirectUri(gauth_callback_url()); - $client->setDeveloperKey($api_key); - $scopes = gauth_google_services_scopes(); - $client->addScope($scopes['oauth2']); - $client->authenticate($_GET['code']); - $account['access_token'] = $client->getAccessToken(); - $client = new Google_Client(); - $client->setApplicationName("Google OAuth2"); - $client->setClientId($client_id); - $client->setClientSecret($client_secret); - $client->setRedirectUri(gauth_callback_url()); - $client->setDeveloperKey($api_key); - $client->setAccessToken($account['access_token']); - $scopes = gauth_google_services_scopes(); - $client->addScope($scopes['oauth2']); + buildGoogleClient($client); + buildAccessToken($client); + $oauth = new Google_Service_Oauth2($client); $info = $oauth->userinfo->get(); - if ($uid = gauth_login_load_google_id($info['id'])) { - $form_state['uid'] = $uid; - user_login_submit(array(), $form_state); - } - else { - $account['client_id'] = variable_get('gauth_login_client_id'); - $account['client_secret'] = variable_get('gauth_login_client_secret'); - $account['developer_key'] = variable_get('gauth_login_developer_key'); - $account['services'] = 'oauth2'; - $account['is_authenticated'] = TRUE; - - if (!$new_user = gauth_login_find_existing_user($info)) { - if (variable_get('gauth_login_create_user', TRUE)) { - $user = new stdClass(); - $user->mail = $info['email']; - $user->name = user_load_by_name($info['name']) ? $info['name'] . time() : $info['name']; - $user->is_new = TRUE; - $user->status = 1; - $new_user = user_save($user); - } - else { - drupal_set_message(t(variable_get('gauth_login_create_user_not_allowed_message', 'Can not find a user with this email. Did you use other google account while registering?'))); - drupal_goto('user/login'); - } - } - $form_state['uid'] = $new_user->uid; - user_login_submit(array(), $form_state); - global $user; - $token = drupal_hash_base64(drupal_random_bytes(55)); - $_SESSION['pass_reset_' . $user->uid] = $token; - if (variable_get('gauth_login_prom_message', TRUE)) { - drupal_set_message(t("Click here to set password", array('@url' => url('user/' . $user->uid . '/edit', array('query' => array('pass-reset-token' => $token))))), 'warning'); - } - $gauth_login = array( - 'google_id' => $info['id'], - 'uid' => $user->uid - ); - drupal_write_record('gauth_login', $gauth_login); - $account['name'] = 'Gauth Login ' . $user->uid; - $account['uid'] = $user->uid; - drupal_write_record('gauth_accounts', $account); - } + $account = buildAccountInfo($info); + userLogin($account, $info); } + + $redirect_url = isset($state['destination']) ? $state['destination'] : ''; drupal_goto($redirect_url); } } -/** - * Finds an existing user based on info from Google. - * - * @param array $info - * The 'userinfo' array from OAuth. - * - * @return object|NULL - * An existing Drupal user object if found; otherwise NULL. - */ -function gauth_login_find_existing_user($info) { - // First, see if there is a user with the given e-mail. - if ($new_user = user_load_by_mail($info['email'])) { - return $new_user; +function checkStateSource($state) { + if (isset($state['src']) && $state['src'] != 'gauth_login') { + return; } +} - // Next, see if any modules have another way of tracking down existing users. - foreach (module_implements('gauth_login_find_existing_user') as $module) { - if ($new_user = module_invoke($module, 'gauth_login_find_existing_user', $info)) { - return $new_user; - } +function validateStateParameter($state) { + if ($state['hash'] != $_SESSION['gauth_login_state']['hash']) { + drupal_set_message(t('Invalid state parameter'), 'error'); + drupal_access_denied(); + return; + } +} + +function buildAccountInfo($info) { + $account['client_id'] = variable_get('gauth_login_client_id'); + $account['client_secret'] = variable_get('gauth_login_client_secret'); + $account['developer_key'] = variable_get('gauth_login_developer_key'); + $account['services'] = 'oauth2'; + $account['is_authenticated'] = TRUE; + $account['uid'] = gauth_login_load_google_id($info['id']); + $account['mail'] = $info['email']; + + if ($account['uid'] == FALSE) { + $account['uid'] = addUserToGauthTables($account, $info); + } + + return $account; +} + +function addUserToGauthTables($account, $info) { + $user = loadUser($info); + $account['name'] = 'Gauth Login ' . $user->uid; + $account['uid'] = $user->uid; + + $gauth_login = array( + 'google_id' => $info['id'], + 'uid' => $user->uid + ); + + drupal_write_record('gauth_login', $gauth_login); + drupal_write_record('gauth_accounts', $account); + + return $account['uid']; +} + +function loadUser($info) { + $user = user_load_by_mail($info['email']); + + if (empty($user)) { + createNewUser($info); + } + + return $user; +} + +function createNewUser($info) { + if (variable_get('gauth_login_create_user', TRUE) && !restrictLoginAccess($info['email'])) { + $user = new stdClass(); + $user->mail = $info['email']; + $user->name = user_load_by_name($info['name']) ? $info['name'] . time() : $info['name']; + $user->is_new = TRUE; + $user->status = 1; + + user_save($user); + resetUserPassword($user); + } + elseif (restrictLoginAccess($info['email'])) { + drupal_set_message(t('Google Login is restricted to %restricted domains.', array('%restricted' => variable_get('gauth_login_domain_restriction')))); + drupal_goto('user/login'); + } + + return $user; +} + +function resetUserPassword($user) { + $token = drupal_hash_base64(drupal_random_bytes(55)); + $_SESSION['pass_reset_' . $user->uid] = $token; + + if (variable_get('gauth_login_prom_message', TRUE)) { + drupal_set_message(t("Click here to set password", array('@url' => url('user/' . $user->uid . '/edit', array('query' => array('pass-reset-token' => $token))))), 'warning'); + } +} + +function restrictLoginAccess($email) { + $domainRestriction = variable_get('gauth_login_domain_restriction', FALSE); + + if ($domainRestriction) { + $domain = '@' . $domainRestriction; + $domainLength = strlen($domain); + $emailDomain = substr($email, -$domainLength); + $restrictAccess = ($emailDomain != '@' . $domainRestriction ? TRUE : FALSE); + } + + return $restrictAccess; +} + +function userLogin($account, $info) { + if (empty(variable_get('gauth_login_domain_restriction')) || !restrictLoginAccess($info['email'])) { + $form_state['uid'] = $account['uid']; + user_login_submit(array(), $form_state); + } + elseif (restrictLoginAccess($info['email'])) { + drupal_set_message(t('Google Login is restricted to %restricted domains.', array('%restricted' => variable_get('gauth_login_domain_restriction')))); + drupal_goto('user/login'); + } + else { + drupal_set_message(t(variable_get('gauth_login_create_user_not_allowed_message', 'Can not find a user with this email. Did you use other google account while registering?'))); + drupal_goto('user/login'); } } @@ -168,49 +193,70 @@ function gauth_login_form_alter(&$form, &$form_state, $form_id) { * Login using google, submit handler */ function gauth_login_user_login_submit() { - if (variable_get('gauth_login_client_id', FALSE)) { + if (variable_get('gauth_login_client_id')) { $info = libraries_load('google-api-php-client'); - if (!$info['loaded']) { - drupal_set_message(t("Can't authenticate with google as library is missing check Status report or Readme for requirements"), 'error'); - return FALSE; - } + checkIfLibraryLoaded($info); + $client = new Google_Client(); - $client->setApplicationName("Google OAuth2"); - $client->setClientId(variable_get('gauth_login_client_id')); - $client->setClientSecret(variable_get('gauth_login_client_secret')); - $client->setRedirectUri(gauth_callback_url()); - $client->setDeveloperKey(variable_get('gauth_login_developer_key')); - $scopes = gauth_google_services_scopes(); - $client->addScope($scopes['oauth2']); - if (!isset($_SESSION['gauth_login_state'])) { - $state = array( - 'src' => 'gauth_login', - 'hash' => md5(rand()) - ); - if (isset($_GET['destination'])) { - $state['destination'] = $_GET['destination']; - unset($_GET['destination']); - } - } - else { - $state = $_SESSION['gauth_login_state']; - } - $_SESSION['gauth_login_state'] = $state; - $state = drupal_json_encode($state); - $client->setState($state); - - $url = $client->createAuthUrl(); - if ($restrict_domain = variable_get('gauth_login_domain_restriction', FALSE)) { - $url .= '&hd=' . $restrict_domain; - } - - drupal_goto($url); + buildGoogleClient($client); + setGauthState($client); + buildGoogleLoginURL($client); } else { drupal_set_message(t('Gauth Login is not configured. Please contact site administrator'), 'error'); } } +function checkIfLibraryLoaded($info) { + if (!$info['loaded']) { + drupal_set_message(t("Can't authenticate with google as library is missing check Status report or Readme for requirements"), 'error'); + return FALSE; + } +} + +function buildGoogleClient($client) { + $client->setApplicationName("Google OAuth2"); + $client->setClientId(variable_get('gauth_login_client_id')); + $client->setClientSecret(variable_get('gauth_login_client_secret')); + $client->setRedirectUri(gauth_callback_url()); + $client->setDeveloperKey(variable_get('gauth_login_developer_key')); + $scopes = gauth_google_services_scopes(); + $client->addScope($scopes['oauth2']); +} + +function buildAccessToken($client) { + $client->authenticate($_GET['code']); + $account['access_token'] = $client->getAccessToken(); + $client->setAccessToken($account['access_token']); +} + +function setGauthState($client) { + if (!isset($_SESSION['gauth_login_state'])) { + $_SESSION['gauth_login_state'] = array( + 'src' => 'gauth_login', + 'hash' => md5(rand()) + ); + if (isset($_GET['destination'])) { + $_SESSION['gauth_login_state']['destination'] = $_GET['destination']; + unset($_GET['destination']); + } + } + + $state = drupal_json_encode($_SESSION['gauth_login_state']); + $client->setState($state); +} + +function buildGoogleLoginURL($client) { + $url = $client->createAuthUrl(); + $restrictDomain = variable_get('gauth_login_domain_restriction', FALSE); + + if ($restrictDomain) { + $url .= '&hd=' . $restrictDomain; + } + + drupal_goto($url); +} + /** * Function returns uid of passed google id */ @@ -230,4 +276,4 @@ function gauth_login_user_delete($user) { db_delete('gauth_login') ->condition('uid', $user->uid) ->execute(); -} +} \ No newline at end of file