18
18
limitations under the License.
19
19
=========================================================================*/
20
20
21
- /** Notification manager for the googleauth module */
21
+ /**
22
+ * Notification manager for the googleauth module.
23
+ *
24
+ * @property Googleauth_UserModel $Googleauth_User
25
+ */
22
26
class Googleauth_Notification extends MIDAS_Notification
23
27
{
28
+ /** @var string */
24
29
public $ moduleName = 'googleauth ' ;
30
+
31
+ /** @var array */
25
32
public $ _models = array ('Setting ' , 'User ' , 'Userapi ' );
33
+
34
+ /** @var array */
26
35
public $ _moduleModels = array ('User ' );
27
36
28
37
/** init notification process */
@@ -31,76 +40,136 @@ public function init()
31
40
$ this ->addCallBack ('CALLBACK_CORE_LOGIN_EXTRA_HTML ' , 'googleAuthLink ' );
32
41
$ this ->addCallBack ('CALLBACK_CORE_USER_DELETED ' , 'handleUserDeleted ' );
33
42
$ this ->addCallBack ('CALLBACK_CORE_USER_COOKIE ' , 'checkUserCookie ' );
43
+ $ this ->addCallBack ('CALLBACK_CORE_USER_LOGOUT ' , 'handleUserLogout ' );
34
44
}
35
45
36
46
/**
37
47
* Constructs the link that is used to initiate a google oauth authentication.
38
48
* This link redirects the user to google so they can approve of the requested
39
49
* oauth scopes, and in turn google will redirect them back to our callback
40
50
* url with an authorization code.
51
+ *
52
+ * @return string
41
53
*/
42
54
public function googleAuthLink ()
43
55
{
56
+ $ baseUrl = Zend_Controller_Front::getInstance ()->getBaseUrl ();
57
+
44
58
$ clientId = $ this ->Setting ->getValueByName (GOOGLE_AUTH_CLIENT_ID_KEY , $ this ->moduleName );
45
- $ scheme = ( array_key_exists ( ' HTTPS ' , $ _SERVER ) && $ _SERVER [ ' HTTPS ' ]) ? ' https:// ' : ' http:// ' ;
46
- $ fc = Zend_Controller_Front:: getInstance ( );
59
+ $ redirectUri = UtilityComponent:: getServerURL (). $ baseUrl . ' / ' . $ this -> moduleName . ' /callback ' ;
60
+ $ additionalScopes = preg_split ( ' /\n|\r/ ' , $ this -> Setting -> getValueByName ( GOOGLE_AUTH_CLIENT_ADDITIONAL_SCOPES_KEY , $ this -> moduleName ), - 1 , PREG_SPLIT_NO_EMPTY );
47
61
48
62
/** @var RandomComponent $randomComponent */
49
63
$ randomComponent = MidasLoader::loadComponent ('Random ' );
50
- $ csrfToken = $ randomComponent ->generateString (30 );
51
- $ redirectUri = $ scheme .$ _SERVER ['HTTP_HOST ' ].$ fc ->getBaseUrl ().'/ ' .$ this ->moduleName .'/callback ' ;
52
- $ scopes = array ('profile ' , 'email ' );
53
-
54
- $ href = 'https://accounts.google.com/o/oauth2/auth?response_type=code ' .'&client_id= ' .urlencode (
55
- $ clientId
56
- ).'&redirect_uri= ' .urlencode ($ redirectUri ).'&scope= ' .urlencode (
57
- implode (
58
- ' ' ,
59
- $ scopes
60
- )
61
- ).'&state= ' .urlencode ($ csrfToken );
62
-
63
- $ userNs = new Zend_Session_Namespace ('Auth_User ' );
64
- $ userNs ->oauthToken = $ csrfToken ;
64
+ $ csrf = $ randomComponent ->generateString (32 );
65
+
66
+ $ client = new Google_Client ();
67
+ $ client ->setAccessType ('offline ' );
68
+ $ client ->setClientId ($ clientId );
69
+ $ client ->setRedirectUri ($ redirectUri );
70
+ $ client ->setScopes (array_merge (array ('email ' , 'profile ' ), $ additionalScopes ));
71
+ $ client ->setState ($ csrf );
72
+
73
+ $ namespace = new Zend_Session_Namespace ('Auth_User ' );
74
+ $ namespace ->oauthToken = $ csrf ;
65
75
session_write_close ();
66
76
67
- return '<div style="margin-top: 10px; display: inline-block;">Or ' .'<a class="googleauth-login" style="text-decoration: underline;" href=" ' .htmlspecialchars ($ href , ENT_QUOTES , 'UTF-8 ' ).'"> ' .'Login with your Google account</a></div><script type="text/javascript" ' .' src=" ' .$ fc ->getBaseUrl (
68
- ).'/modules/ ' .$ this ->moduleName .'/public/js/login/googleauth.login.js"></script> ' ;
77
+ $ authUrl = $ client ->createAuthUrl ();
78
+
79
+ return '<div style="margin-top: 10px; display: inline-block;">Or ' .'<a class="googleauth-login" style="text-decoration: underline;" href=" ' .htmlspecialchars ($ authUrl , ENT_QUOTES , 'UTF-8 ' ).'"> ' .'Login with your Google account</a></div><script type="text/javascript" ' .' src=" ' .UtilityComponent::getServerURL ().$ baseUrl .'/modules/ ' .$ this ->moduleName .'/public/js/login/googleauth.login.js"></script> ' ;
69
80
}
70
81
71
82
/**
72
83
* If a user is deleted, we must delete any corresponding google auth user.
84
+ *
85
+ * @param array $args
73
86
*/
74
- public function handleUserDeleted ($ params )
87
+ public function handleUserDeleted ($ args )
75
88
{
76
- $ this ->Googleauth_User ->deleteByUser ($ params ['userDao ' ]);
89
+ $ this ->Googleauth_User ->deleteByUser ($ args ['userDao ' ]);
77
90
}
78
91
79
- /** Check user cookie */
92
+ /**
93
+ * Check user cookie.
94
+ *
95
+ * @param array $args
96
+ * @return false|UserDao
97
+ * @throws Zend_Exception
98
+ */
80
99
public function checkUserCookie ($ args )
81
100
{
82
101
$ cookie = $ args ['value ' ];
83
102
84
103
if (strpos ($ cookie , 'googleauth ' ) === 0 ) {
85
- list (, $ userId , $ apikey ) = preg_split ('/:/ ' , $ cookie );
86
- $ userDao = $ this ->User ->load ($ userId );
104
+ list (, $ userId , $ apiKey ) = preg_split ('/:/ ' , $ cookie );
87
105
88
- if (!$ userDao ) {
106
+ $ userDao = $ this ->User ->load ($ userId );
107
+ if ($ userDao === false ) {
89
108
return false ;
90
109
}
91
110
92
- $ userapi = $ this ->Userapi ->getByAppAndUser ('Default ' , $ userDao );
93
-
94
- if (!$ userapi ) {
111
+ $ userApiDao = $ this ->Userapi ->getByAppAndUser ('Default ' , $ userDao );
112
+ if ($ userApiDao === false || md5 ($ userApiDao ->getApikey ()) !== $ apiKey ) {
95
113
return false ;
96
114
}
97
- if (md5 ($ userapi ->getApikey ()) === $ apikey ) {
98
- return $ userDao ;
99
- } else {
100
- return false ;
115
+
116
+ /** @var Zend_Controller_Request_Http $request */
117
+ $ request = Zend_Controller_Front::getInstance ()->getRequest ();
118
+ $ accessToken = $ request ->getCookie (GOOGLE_AUTH_ACCESS_TOKEN_COOKIE_NAME , false );
119
+
120
+ if ($ accessToken !== false ) {
121
+ $ clientId = $ this ->Setting ->getValueByName (GOOGLE_AUTH_CLIENT_ID_KEY , $ this ->moduleName );
122
+ $ clientSecret = $ this ->Setting ->getValueByName (GOOGLE_AUTH_CLIENT_SECRET_KEY , $ this ->moduleName );
123
+
124
+ $ client = new Google_Client ();
125
+ $ client ->setAccessToken ($ accessToken );
126
+ $ client ->setAccessType ('offline ' );
127
+ $ client ->setClientId ($ clientId );
128
+ $ client ->setClientSecret ($ clientSecret );
129
+
130
+ if ($ client ->isAccessTokenExpired ()) {
131
+ $ refreshToken = $ client ->getRefreshToken ();
132
+ $ client ->refreshToken ($ refreshToken );
133
+
134
+ $ date = new DateTime ();
135
+ $ interval = new DateInterval ('P1M ' );
136
+ setcookie (
137
+ GOOGLE_AUTH_ACCESS_TOKEN_COOKIE_NAME ,
138
+ $ client ->getAccessToken (),
139
+ $ date ->add ($ interval )->getTimestamp (),
140
+ '/ ' ,
141
+ $ request ->getHttpHost (),
142
+ (int ) Zend_Registry::get ('configGlobal ' )->get ('cookie_secure ' , 1 ) === 1 ,
143
+ true
144
+ );
145
+ }
101
146
}
102
- } else {
103
- return false ;
147
+
148
+ return $ userDao ;
104
149
}
150
+
151
+ return false ;
152
+ }
153
+
154
+ /**
155
+ * Handle the core CALLBACK_CORE_USER_LOGOUT notification.
156
+ *
157
+ * @param array $args
158
+ */
159
+ public function handleUserLogout ($ args )
160
+ {
161
+ /** @var Zend_Controller_Request_Http $request */
162
+ $ request = Zend_Controller_Front::getInstance ()->getRequest ();
163
+ $ date = new DateTime ();
164
+ $ interval = new DateInterval ('P1M ' );
165
+ setcookie (
166
+ GOOGLE_AUTH_ACCESS_TOKEN_COOKIE_NAME ,
167
+ null ,
168
+ $ date ->sub ($ interval )->getTimestamp (),
169
+ '/ ' ,
170
+ $ request ->getHttpHost (),
171
+ (int ) Zend_Registry::get ('configGlobal ' )->get ('cookie_secure ' , 1 ) === 1 ,
172
+ true
173
+ );
105
174
}
106
175
}
0 commit comments