Blame view

common/components/nodge/eauth/src/openid/Service.php 4.28 KB
f91c1ae8   Dmitryi   new commit compon...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  <?php
  /**
   * OpenID Service class file.
   *
   * @author Maxim Zemskov <nodge@yandex.ru>
   * @link http://github.com/Nodge/yii2-eauth/
   * @license http://www.opensource.org/licenses/bsd-license.php
   */
  
  namespace nodge\eauth\openid;
  
  use \Yii;
  use \LightOpenID;
  use yii\web\HttpException;
  use nodge\eauth\ServiceBase;
  use nodge\eauth\IAuthService;
  use nodge\eauth\ErrorException;
  
  /**
   * EOpenIDService is a base class for all OpenID providers.
   *
   * @package application.extensions.eauth
   */
  abstract class Service extends ServiceBase implements IAuthService
  {
  
  	/**
  	 * @var string a pattern that represents the part of URL-space for which an OpenID Authentication request is valid.
  	 * See the spec for more info: http://openid.net/specs/openid-authentication-2_0.html#realms
  	 * Note: a pattern can be without http(s):// part
  	 */
  	public $realm;
  
  	/**
  	 * @var LightOpenID the openid library instance.
  	 */
  	private $auth;
  
  	/**
  	 * @var string the OpenID authorization url.
  	 */
  	protected $url;
  
  	/**
  	 * @var array the OpenID required attributes.
  	 */
  	protected $requiredAttributes = [];
  
  	/**
  	 * @var array the OpenID optional attributes.
  	 */
  	protected $optionalAttributes = [];
  
  
  	/**
  	 * Initialize the component.
  	 */
  	public function init()
  	{
  		parent::init();
  		$this->auth = new LightOpenID(Yii::$app->getRequest()->getHostInfo());
  	}
  
  	/**
  	 * Authenticate the user.
  	 *
  	 * @return boolean whether user was successfuly authenticated.
  	 * @throws ErrorException
  	 * @throws HttpException
  	 */
  	public function authenticate()
  	{
  		if (!empty($_REQUEST['openid_mode'])) {
  			switch ($_REQUEST['openid_mode']) {
  				case 'id_res':
  					$this->id_res();
  					return true;
  					break;
  
  				case 'cancel':
  					$this->cancel();
  					break;
  
  				default:
  					throw new HttpException(400, Yii::t('yii', 'Your request is invalid.'));
  					break;
  			}
  		} else {
  			$this->request();
  		}
  
  		return false;
  	}
  
  	/**
  	 * @throws ErrorException
  	 */
  	protected function id_res()
  	{
  		try {
  			if ($this->auth->validate()) {
  				$this->attributes['id'] = $this->auth->identity;
  				$this->loadRequiredAttributes();
  				$this->loadOptionalAttributes();
  				$this->authenticated = true;
  			} else {
  				throw new ErrorException(Yii::t('eauth', 'Unable to complete the authentication because the required data was not received.', ['provider' => $this->getServiceTitle()]));
  			}
  		} catch (\Exception $e) {
  			throw new ErrorException($e->getMessage(), $e->getCode());
  		}
  	}
  
  	/**
  	 * @throws ErrorException
  	 */
  	protected function loadOptionalAttributes()
  	{
  		$attributes = $this->auth->getAttributes();
  		foreach ($this->optionalAttributes as $key => $attr) {
  			if (isset($attributes[$attr[1]])) {
  				$this->attributes[$key] = $attributes[$attr[1]];
  			}
  		}
  	}
  
  	/**
  	 *
  	 */
  	protected function loadRequiredAttributes()
  	{
  		$attributes = $this->auth->getAttributes();
  		foreach ($this->requiredAttributes as $key => $attr) {
  			if (isset($attributes[$attr[1]])) {
  				$this->attributes[$key] = $attributes[$attr[1]];
  			} else {
  				throw new ErrorException(Yii::t('eauth', 'Unable to complete the authentication because the required data was not received.', ['provider' => $this->getServiceTitle()]));
  			}
  		}
  	}
  
  	/**
  	 * @throws ErrorException
  	 */
  	protected function request()
  	{
  		$this->auth->identity = $this->url; //Setting identifier
  
  		$this->auth->required = []; //Try to get info from openid provider
  		foreach ($this->requiredAttributes as $attribute) {
  			$this->auth->required[$attribute[0]] = $attribute[1];
  		}
  		foreach ($this->optionalAttributes as $attribute) {
  			$this->auth->required[$attribute[0]] = $attribute[1];
  		}
  
  		$this->auth->realm = $this->getRealm();
  		$this->auth->returnUrl = Yii::$app->getRequest()->getHostInfo() . Yii::$app->getRequest()->getUrl(); //getting return URL
  
  		try {
  			$url = $this->auth->authUrl();
  			Yii::$app->getResponse()->redirect($url)->send();
  		} catch (\Exception $e) {
  			throw new ErrorException($e->getMessage(), $e->getCode());
  		}
  	}
  
  	/**
  	 * @return string
  	 */
  	protected function getRealm()
  	{
  		if (isset($this->realm)) {
  			if (!preg_match('#^[a-z]+\://#', $this->realm)) {
  				return 'http' . (Yii::$app->getRequest()->getIsSecureConnection() ? 's' : '') . '://' . $this->realm;
  			} else {
  				return $this->realm;
  			}
  		} else {
  			return Yii::$app->getRequest()->getHostInfo();
  		}
  	}
  }