public function linkSocialProfile() { $settings = \Users\Models\Settings::fetch(); if (!$settings->isSocialLoginEnabled()) { \Dsc\System::addMessage('Social login is not supported.', 'error'); \Base::instance()->reroute("/user"); } $user = $this->getIdentity(); if (empty($user->id) || !empty($user->__safemode)) { $this->app->reroute('/user'); return; } $provider = strtolower($this->app->get('PARAMS.provider')); if (!$settings->isSocialLoginEnabled($provider)) { \Dsc\System::addMessage('This social profile is not supported.', 'error'); \Base::instance()->reroute("/user"); } $hybridauth_config = \Users\Models\Settings::fetch(); $config = (array) $hybridauth_config->{'social'}; \Dsc\System::instance()->get('session')->set('social_login.failure.redirect', '/user/social-profiles'); if (empty($config['base_url'])) { $config['base_url'] = $this->app->get('SCHEME') . '://' . $this->app->get('HOST') . $this->app->get('BASE') . '/login/social'; } $custom_redirect = \Dsc\System::instance()->get('session')->get('site.login.redirect'); try { // create an instance for Hybridauth with the configuration file path as parameter $hybridauth = new \Hybrid_Auth($config); // try to authenticate the selected $provider $adapter = $hybridauth->authenticate($provider); // grab the user profile $user_profile = $adapter->getUserProfile(); // OK, we have the social identity. // Let's make sure it's unique in our system $filter = 'social.' . $provider . '.profile.identifier'; $found = (new \Users\Models\Users())->setCondition($filter, $user_profile->identifier)->getItem(); if (!empty($found->id) && (string) $found->id != (string) $user->id) { // errrrr, only allow a social ID to be linked to one account at a time \Dsc\System::addMessage('This social profile is already registered with us.', 'error'); // redirect to the requested target, or the default if none requested $redirect = $custom_redirect ? $custom_redirect : '/user'; \Dsc\System::instance()->get('session')->set('site.login.redirect', null); \Base::instance()->reroute($redirect); return; } // add the social id to the user $user->set('social.' . $provider . '.profile', (array) $adapter->getUserProfile()); $user->set('social.' . $provider . '.access_token', (array) $adapter->getAccessToken()); $user->save(); } catch (\Exception $e) { $user_error = null; switch ($e->getCode()) { case 0: $error = "Unspecified error."; break; case 1: $error = "Hybridauth configuration error."; break; case 2: $error = "Provider not properly configured."; break; case 3: $error = "Unknown or disabled provider."; break; case 4: $error = "Missing provider application credentials."; break; case 5: $error = "Authentication failed. The user has canceled the authentication or the provider refused the connection."; $user_error = "Authentication failed."; break; case 6: $error = "User profile request failed. Most likely the user is not connected to the provider and he should to authenticate again."; $user_error = "We were unable to get your profile. Please authenticate again with the profile provider."; $adapter->logout(); break; case 7: $error = "User not connected to the provider."; $user_error = "No profile found with the provider. Missing connection."; $adapter->logout(); break; } if ($this->app->get('DEBUG')) { // if debug mode is enabled, display the full error $error .= "<br /><br /><b>Original error message:</b> " . $e->getMessage(); $error .= "<hr /><pre>Trace:<br />" . $e->getTraceAsString() . "</pre>"; } else { // otherwise, display something simple $error = $user_error; } \Dsc\System::addMessage('Linking failed', 'error'); \Dsc\System::addMessage($error, 'error'); $redirect = $custom_redirect ? $custom_redirect : '/user'; $this->app->reroute($redirect); } // redirect to the requested target, or the default if none requested $redirect = $custom_redirect ? $custom_redirect : '/user'; \Dsc\System::instance()->get('session')->set('site.login.redirect', null); $this->app->reroute($redirect); }
<?php $settings = \Users\Models\Settings::fetch(); ?> <div class="social-login-providers"> <?php if ($settings->isSocialLoginEnabled('facebook')) { ?> <div class="form-group"> <a href="./login/social/auth/facebook" class="btn btn-facebook btn-default"> <i class="fa fa-facebook"></i> <span>Facebook</span> </a> </div> <?php } ?> <?php if ($settings->isSocialLoginEnabled('twitter')) { ?> <div class="form-group"> <a href="./login/social/auth/twitter" class="btn btn-twitter btn-default"> <i class="fa fa-twitter"></i> <span>Twitter</span> </a> </div> <?php } ?>
?> </select> </div> </div> </div> <div class="row"> <div class="col-md-2"> <h4>Social Profile</h4> </div> <div class="col-md-10"> <div class="form-group"> <select id="social_filter" name="filter[social-profile]" class="form-control"> <option value="">All Social Profiles</option> <?php $providers = \Users\Models\Settings::fetch()->enabledSocialProviders(); foreach ((array) $providers as $network) { ?> <option <?php if ($state->get('filter.social-profile') == $network) { echo 'selected'; } ?> value="<?php echo $network; ?> "><?php echo $network; ?> </option> <?php
/** * Target for the completeProfileForm submission */ public function completeProfile() { $settings = \Users\Models\Settings::fetch(); // check, if front-end registration is enabled if ($settings->{'general.registration.enabled'} == '0') { $f3->reroute('/login'); } if (!$settings->isSocialLoginEnabled()) { \Dsc\System::addMessage('Social login is not supported.', 'error'); \Base::instance()->reroute("/login"); } $f3 = \Base::instance(); try { $data = \Dsc\System::instance()->get('session')->get('users.incomplete_provider_data'); $data['email'] = $this->input->get('email', null, 'string'); $data['username'] = $this->input->get('username', null, 'string'); // we just got an email from a customer, so we need to verify it $user = \Users\Models\Users::createNewUser($data, 'auto_login_with_validation'); // social login should always login the user if successful, // so login the user if they aren't already logged in if (empty($this->getIdentity()->id)) { \Dsc\System::instance()->get('auth')->login($user); } \Dsc\System::instance()->get('session')->set('users.incomplete_provider_data', array()); } catch (\Exception $e) { switch ($e->getCode()) { case \Users\Models\Users::E_EMAIL_EXISTS: // This email is already registered // Push the user back to the login page, // and tell them that they must first sign-in using another method (the one they previously setup), // then upon login, they can link this current social provider to their existing account \Dsc\System::addMessage('This email is already registered.', 'error'); \Dsc\System::addMessage('Please login using the registered email address or with the other social profile that also uses this email address.', 'error'); \Dsc\System::addMessage('Once you are logged in, you may link additional social profiles to your account.', 'error'); $f3->reroute('/login'); break; default: \Dsc\System::addMessage('Registration failed.', 'error'); \Dsc\System::addMessage($e->getMessage(), 'error'); \Dsc\System::instance()->setUserState('users.site.login.complete_profile.flash_filled', true); $flash = \Dsc\Flash::instance(); $flash->store($data); $f3->reroute('/login/completeProfile'); break; } return; } // if we have reached here, then all is right with the world. // redirect to the requested target, or the default if none requested $redirect = '/user'; if ($custom_redirect = \Dsc\System::instance()->get('session')->get('site.login.redirect')) { $redirect = $custom_redirect; } \Dsc\System::instance()->get('session')->set('site.login.redirect', null); $f3->reroute($redirect); }
public function register() { $f3 = \Base::instance(); $checkout_method = strtolower($this->input->get('checkout_method', null, 'alnum')); switch ($checkout_method) { // if $checkout_method == guest // store email in cart object and then continue // create a guest mongoid case "guest": $real_email = trim(strtolower($this->input->get('email_address', null, 'string'))); if (\Users\Models\Users::emailExists($real_email)) { \Dsc\System::addMessage('This email is already registered. Please login to continue. <a href="./user/forgot-password">If necessary, you can recover your password here.</a>', 'error'); $this->app->reroute('/shop/checkout'); return; } $mongo_id = (string) new \MongoId(); $email = 'guest-' . $mongo_id . '@' . $mongo_id . '.' . $mongo_id; $password = \Users\Models\Users::generateRandomString(); $data = array('first_name' => 'Guest', 'last_name' => 'User', 'email' => $email, 'guest_email' => $real_email, 'new_password' => $password, 'confirm_new_password' => $password); $user = (new \Users\Models\Users())->bind($data); try { // this will handle other validations, such as username uniqueness, etc $user->guest = true; $user->active = false; $user->save(); } catch (\Exception $e) { \Dsc\System::addMessage('Could not create guest account', 'error'); \Dsc\System::addMessage($e->getMessage(), 'error'); \Dsc\System::instance()->setUserState('shop.checkout.register.flash_filled', true); $flash = \Dsc\Flash::instance(); $flash->store(array()); $this->app->reroute('/shop/checkout'); return; } // if we have reached here, then all is right with the form $flash = \Dsc\Flash::instance(); $flash->store(array()); // login the user, trigger Listeners \Dsc\System::instance()->get('auth')->login($user); $this->app->reroute('/shop/checkout'); break; // if $checkout_method == register // validate data // create user // redirect back to checkout // if $checkout_method == register // validate data // create user // redirect back to checkout case "register": $email = trim(strtolower($this->input->get('email_address', null, 'string'))); $data = array('first_name' => $this->input->get('first_name', null, 'string'), 'last_name' => $this->input->get('last_name', null, 'string'), 'email' => $email, 'new_password' => $this->input->get('new_password', null, 'string'), 'confirm_new_password' => $this->input->get('confirm_new_password', null, 'string')); $user = (new \Users\Models\Users())->bind($data); // Check if the email already exists and give a custom message if so if (!empty($user->email) && ($existing = $user->emailExists($user->email))) { if (empty($user->id) || $user->id != $existing->id) { \Dsc\System::addMessage('This email is already registered.', 'error'); \Dsc\System::instance()->setUserState('shop.checkout.register.flash_filled', true); $flash = \Dsc\Flash::instance(); $flash->store($user->cast()); $this->app->reroute('/shop/checkout'); return; } } try { // this will handle other validations, such as username uniqueness, etc $settings = \Users\Models\Settings::fetch(); $registration_action = $settings->{'general.registration.action'}; switch ($registration_action) { case "auto_login": $user->active = true; $user->save(); break; case "auto_login_with_validation": $user->active = false; $user->save(); $user->sendEmailValidatingEmailAddress(); break; default: $user->active = false; $user->save(); $user->sendEmailValidatingEmailAddress(); break; } } catch (\Exception $e) { \Dsc\System::addMessage('Could not create account.', 'error'); \Dsc\System::addMessage($e->getMessage(), 'error'); \Dsc\System::instance()->setUserState('shop.checkout.register.flash_filled', true); $flash = \Dsc\Flash::instance(); $flash->store($user->cast()); $f3->reroute('/shop/checkout'); return; } // if we have reached here, then all is right with the form $flash = \Dsc\Flash::instance(); $flash->store(array()); // login the user, trigger Listeners \Dsc\System::instance()->get('auth')->login($user); $this->app->reroute('/shop/checkout'); break; // if $checkout_method something else, // add message? // redirect back to checkout // if $checkout_method something else, // add message? // redirect back to checkout default: \Dsc\System::addMessage('Invalid Checkout Method', 'error'); $this->app->reroute('/shop/checkout'); break; } }
public function unlinkedSocialProfiles() { $settings = \Users\Models\Settings::fetch(); $providers = $settings->enabledSocialProviders(); if (empty($this->social)) { return $providers; } foreach ($this->social as $network => $id) { $key = array_search(strtolower($network), $providers); if ($key !== false) { unset($providers[$key]); } } return $providers; }
/** * Generates auto login token for the user which is valid for next 24 hours * * @param \Users\Models\Users $user * @param boolean $fore_regeneration In case the token has expired, forge generating a new one and return in * * @return Token for user as string (null when the token has expired) */ public function getAutoLoginToken(\Users\Models\Users $user, $force_regeneration = false) { if (empty($user->auto_login)) { $settings = \Users\Models\Settings::fetch(); // let's generate a new token $salt = mt_rand(); $arr = array(); $arr['token'] = $this->generateAutoLoginToken($user, $salt); $arr['valid'] = time() + $settings->get('general.login.auto_login_token_lifetime') * 60; // valid for next 24h $user->auto_login = $arr; $user->save(); return $arr['token']; } else { if ($user->{'auto_login.valid'} < time()) { // auto_login token has expired so let's notify user about that if ($force_regeneration) { // for example, when you want to add this token to URL and you already generated one token a few days ago $settings = \Users\Models\Settings::fetch(); $salt = mt_rand(); $arr = array(); $arr['token'] = $this->generateAutoLoginToken($user, $salt); $arr['valid'] = time() + $settings->get('general.login.auto_login_token_lifetime') * 60; // valid for next 24h $user->auto_login = $arr; $user->save(); return $arr['token']; } else { return null; } } else { return $user->{'auto_login.token'}; } } }