csrfKey; } else { $state = \IPS\Dispatcher::i()->controllerLocation . "-" . \IPS\Session::i()->csrfKey; } return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->vkontakte( "https://oauth.vk.com/authorize?client_id={$this->settings['app_id']}&scope=email&redirect_uri=".urlencode( $url ) . "&state={$state}&response_type=code" ); } /** * Authenticate * * @param string $url The URL for the login page * @param \IPS\Member $member If we want to integrate this login method with an existing member, provide the member object * @return \IPS\Member * @throws \IPS\Login\Exception */ public function authenticate( $url, $member=NULL ) { $url = $url->setQueryString( 'loginProcess', 'vkontakte' ); try { /* Get a token */ try { $response = \IPS\Http\Url::external( "https://oauth.vk.com/access_token?client_id={$this->settings['app_id']}&redirect_uri=".(string) \IPS\Http\Url::internal( 'applications/core/interface/vkontakte/auth.php', 'none' )."&client_secret={$this->settings['app_secret']}&code=".\IPS\Request::i()->code )->request()->get()->decodeJson(); } catch( \RuntimeException $e ) { throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR ); } /* Get the user data */ $userData = $response; if(!isset($userData['email'])) throw new \IPS\Login\Exception( 'В вашем аккаунте ВК отсутствует email, укажите его!', \IPS\Login\Exception::INTERNAL_ERROR ); /* Find or create member */ $newMember = FALSE; if ( $member === NULL ) { $member = \IPS\Member::load( $userData['email'], 'email' ); if ( !$member->member_id ) { $member = new \IPS\Member; if ( \IPS\Settings::i()->reg_auth_type == 'admin' or \IPS\Settings::i()->reg_auth_type == 'admin_user' ) { $member->members_bitoptions['validating'] = TRUE; } $member->member_group_id = \IPS\Settings::i()->member_group; $member->email = $userData['email']; $member->profilesync = json_encode( array( 'vkontakte' => array( 'photo' => TRUE, 'cover' => FALSE, 'status' => TRUE ) ) ); $newMember = TRUE; $name1 = \IPS\Http\Url::external( "https://api.vk.com/method/users.get?user_id={$userData['user_id']}&v=5.29&access_token={$response['access_token']}&fields=first_name,last_name,screen_name,bdate,nickname" )->request()->get()->decodeJson(); $member->name = $name1['response'][0]['nickname']; if ( empty($member->name) AND $this->settings['real_name'] ) { $name = $name1['response'][0]['first_name'].' '.$name1['response'][0]['last_name']; $existingUsername = \IPS\Member::load( $name, 'name' ); if ( !$existingUsername->member_id ) { $member->name = $name; } } } } $member->vk_uid = $userData['user_id']; $member->vk_token = $response['access_token']; $member->save(); /* Sync */ if ( $newMember ) { if ( \IPS\Settings::i()->reg_auth_type == 'admin_user' ) { \IPS\Db::i()->update( 'core_validating', array( 'user_verified' => 1 ), array( 'member_id=?', $member->member_id ) ); } $sync = new \IPS\core\ProfileSync\VK( $member ); $sync->sync(); } /* Return */ return $member; } catch ( \IPS\Http\Request\Exception $e ) { throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR ); } } public static function link( \IPS\Member $member, $details ) { try { $userData = \IPS\Http\Url::external( "https://api.vk.com/method/users.get?uid={$details[1]}&access_token={$details[0]}&fields=first_name,last_name,screen_name,bdate,nickname" )->request()->get()->decodeJson(); $userData = $userData['response'][0]; $member->vk_id = $details[1]; $member->vk_token = $details[0]; $member->save(); }catch(\Exception $e) {} } /** * ACP Settings Form * * @param string $url URL to redirect user to after successful submission * @return array List of settings to save - settings will be stored to core_login_handlers.login_settings DB field * @code return array( 'savekey' => new \IPS\Helpers\Form\[Type]( ... ), ... ); * @endcode */ public function acpForm() { $where = array( array( 'template_group=?', 'login' ) ); $where[] = array( 'template_app=?', 'core' ); $where[] = array( 'template_location=?', 'global' ); $results = array(); $selects = \IPS\Db::i()->select( 'template_name', 'core_theme_templates', $where ); $selects->rewind(); while($selects->valid()) { $results[ $selects->current() ] = $selects->current(); $selects->next(); } $results = array_unique( $results ); //if(\IPS\IN_DEV) { if(!in_array('vkontakte',$results)) { ob_start();?> {lang="login_vkontakte"} \n/', $html, $params ); /* Strip it */ $html = ( isset($params[0]) ) ? str_replace( $params[0], '', $html ) : $html; $id=0; \IPS\Db::i()->insert( 'core_theme_templates', array( 'template_set_id' => $id, 'template_app' => 'core', 'template_added_to' => $id, 'template_location' => 'global', 'template_group' => 'login', 'template_name' => 'vkontakte', 'template_data' => ( isset( $params[1] ) ) ? $params[1] : '', 'template_content' => $html, 'template_updated' => time(), 'template_unique_key' => md5( $id . ';' . 'core' . ';' . 'global' . ';' . 'login' . ';' . ( 'vkontakte' ) ), 'template_removable' => $id ) ); \IPS\Theme::load( \IPS\Theme::i()->defaultTheme() )->compileTemplates( 'core' ); } /*}elseif(!in_array('vkontakte',$results)) { \IPS\Output::i()->sidebar['actions'] = array( 'help' => array( 'link' => \IPS\Http\Url::internal( '&app=core&module=settings&controller=login&do=form&id=vkontakte' ), 'title' => 'Шаблоны не синхронизированы. Включите DEV-режим и перезагрузите страницу!', ), ); }*/ return array( 'app_id' => new \IPS\Helpers\Form\Text( 'login_vkontakte_app', ( isset( $this->settings['app_id'] ) ) ? $this->settings['app_id'] : '', TRUE ), 'app_secret' => new \IPS\Helpers\Form\Text( 'login_vkontakte_secret', ( isset( $this->settings['app_secret'] ) ) ? $this->settings['app_secret'] : '', TRUE ), 'real_name' => new \IPS\Helpers\Form\YesNo( 'login_real_name', ( isset( $this->settings['real_name'] ) ) ? $this->settings['real_name'] : FALSE, TRUE ) ); } /** * Test Settings * * @return bool * @throws \InvalidArgumentException */ public function testSettings() { return TRUE; } /** * Can a member sign in with this login handler? * Used to ensure when a user disassociates a social login that they have some other way of logging in * * @param \IPS\Member $member The member * @return bool */ public function canProcess( \IPS\Member $member ) { return ( $member->vk_id and $member->vk_token ); } /** * Can a member change their email/password with this login handler? * * @param string $type 'email' or 'password' * @param \IPS\Member $member The member * @return bool */ public function canChange( $type, \IPS\Member $member ) { return FALSE; } }