@@ -27,6 +27,7 @@ class PluginSession extends SSOData
2727{
2828 const QUERY_PARAM_JWT = 'jwt ' ;
2929 const QUERY_PARAM_PID = 'pid ' ;
30+ const QUERY_PARAM_SID = 'sessionID ' ;
3031 const QUERY_PARAM_USERVIEW = 'userView ' ;
3132
3233 const KEY_SSO = 'sso ' ;
@@ -37,11 +38,21 @@ class PluginSession extends SSOData
3738 */
3839 private $ pluginInstanceId = null ;
3940
41+ /**
42+ * @var String $sessionId the id of the current session.
43+ */
44+ private $ sessionId = null ;
45+
4046 /**
4147 * @var boolean $userView flag for userView mode.
4248 */
4349 private $ userView = true ;
4450
51+ /**
52+ * @var SSOToken token data from the parsed jwt
53+ */
54+ private $ sso = null ;
55+
4556 /**
4657 * Constructor
4758 *
@@ -64,13 +75,12 @@ public function __construct($pluginId, $appSecret, SessionHandlerInterface $sess
6475 if ($ sessionHandler )
6576 session_set_save_handler ($ sessionHandler , true );
6677
67- $ this ->openSession ($ pluginId );
6878
6979 $ pid = isset ($ _GET [self ::QUERY_PARAM_PID ]) ? $ _GET [self ::QUERY_PARAM_PID ] : null ;
7080 $ jwt = isset ($ _GET [self ::QUERY_PARAM_JWT ]) ? $ _GET [self ::QUERY_PARAM_JWT ] : null ;
81+ $ sid = isset ($ _GET [self ::QUERY_PARAM_SID ]) ? $ _GET [self ::QUERY_PARAM_SID ] : null ;
7182
7283 // lets hint to bad class usage, as these cases should never happen.
73-
7484 if ($ pid && $ jwt ) {
7585 throw new SSOAuthenticationException ('Tried to initialize the session with both PID and JWT provided. ' );
7686 }
@@ -80,50 +90,35 @@ public function __construct($pluginId, $appSecret, SessionHandlerInterface $sess
8090 }
8191
8292 $ this ->pluginInstanceId = $ pid ;
93+ $ this ->sessionId = $ sid ;
8394
8495 // we update the SSO info every time we get a token
8596 if ($ jwt ) {
86-
8797 // decrypt the token
88- $ sso = new SSOToken ($ appSecret , $ jwt , $ leeway );
89- $ ssoData = $ sso ->getData ();
90-
91- // dispatch remote calls from Staffbase
92- if ($ sso ->isDeleteInstanceCall () && $ remoteCallHandler ) {
93-
94- // we will accept unhandled calls with a warning
95- $ result = true ;
96-
97- $ instanceId = $ sso ->getInstanceId ();
98+ $ this ->sso = new SSOToken ($ appSecret , $ jwt , $ leeway );
9899
99- if ($ remoteCallHandler instanceOf DeleteInstanceCallHandlerInterface) {
100- $ result = $ remoteCallHandler ->deleteInstance ($ instanceId );
101- } else {
102- error_log ("Warning: An instance deletion call for instance $ instanceId was not handled. " );
103- }
100+ $ this ->pluginInstanceId = $ this ->sso ->getInstanceId ();
101+ $ this ->sessionId = $ this ->sso ->getSessionId ();
102+ }
104103
105- // finish the remote call
106- if ($ result )
107- $ remoteCallHandler ->exitSuccess ();
108- else
109- $ remoteCallHandler ->exitFailure ();
104+ // dispatch remote calls from Staffbase
105+ if ($ this ->sso ) {
106+ $ this ->deleteInstance ($ remoteCallHandler );
107+ }
110108
111- $ this ->exitRemoteCall ();
112- }
109+ $ this ->openSession ($ pluginId );
113110
114- // update data
115- $ this ->pluginInstanceId = $ sso ->getInstanceId ();
116- $ _SESSION [$ this ->pluginInstanceId ][self ::KEY_SSO ] = $ ssoData ;
111+ if ($ this ->sso !== null ) {
112+ $ _SESSION [$ this ->pluginInstanceId ][self ::KEY_SSO ] = $ this ->sso ->getData ();
117113 }
118114
115+ // decide if we are in user view or not
116+ $ this ->userView = !$ this ->isAdminView ();
117+
119118 // requests with spoofed PID are not allowed
120119 if (!isset ($ _SESSION [$ this ->pluginInstanceId ][self ::KEY_SSO ])
121- || empty ($ _SESSION [$ this ->pluginInstanceId ][self ::KEY_SSO ]))
120+ || empty ($ _SESSION [$ this ->pluginInstanceId ][self ::KEY_SSO ]))
122121 throw new SSOAuthenticationException ('Tried to access an instance without previous authentication. ' );
123-
124- // decide if we are in user view or not
125- if ($ this ->isEditor () && (!isset ($ _GET [self ::QUERY_PARAM_USERVIEW ]) || $ _GET [self ::QUERY_PARAM_USERVIEW ] !== 'true ' ))
126- $ this ->userView = false ;
127122 }
128123
129124 /**
@@ -134,6 +129,40 @@ public function __destruct() {
134129 $ this ->closeSession ();
135130 }
136131
132+ private function isAdminView () {
133+ return $ this ->isEditor () && (!isset ($ _GET [self ::QUERY_PARAM_USERVIEW ]) || $ _GET [self ::QUERY_PARAM_USERVIEW ] !== 'true ' );
134+ }
135+
136+ private function deleteInstance ($ remoteCallHandler ){
137+ if (!$ this ->sso ->isDeleteInstanceCall () || !$ remoteCallHandler ) {
138+ return ;
139+ }
140+
141+ $ instanceId = $ this ->sso ->getInstanceId ();
142+
143+ if ($ remoteCallHandler instanceOf DeleteInstanceCallHandlerInterface) {
144+ $ result = $ remoteCallHandler ->deleteInstance ($ instanceId );
145+ } else {
146+ // we will accept unhandled calls with a warning
147+ $ result = true ;
148+ error_log ("Warning: An instance deletion call for instance $ instanceId was not handled. " );
149+ }
150+
151+ // finish the remote call
152+ if ($ result )
153+ $ remoteCallHandler ->exitSuccess ();
154+ else
155+ $ remoteCallHandler ->exitFailure ();
156+
157+ $ this ->exitRemoteCall ();
158+ }
159+
160+ private function createCompatibleSessionId (String $ string ): String
161+ {
162+ $ allowedChars = '/[^a-zA-Z0-9,-]/ ' ;
163+ return preg_replace ($ allowedChars , '- ' , $ string );
164+ }
165+
137166 /**
138167 * Exit the script
139168 *
@@ -149,8 +178,11 @@ protected function exitRemoteCall() {
149178 *
150179 * @param string $name of the session
151180 */
152- protected function openSession ($ name ) {
181+ protected function openSession (string $ name ) {
182+
183+ $ sessionId = $ this ->createCompatibleSessionId ($ this ->sessionId );
153184
185+ session_id ($ sessionId );
154186 session_name ($ name );
155187 session_start ();
156188 }
@@ -167,12 +199,12 @@ protected function closeSession() {
167199 * (DEPRECATED) Translate a base64 string to PEM encoded public key.
168200 *
169201 * @param string $data base64 encoded key
170- *
202+ * @deprecated
171203 * @return string PEM encoded key
172204 */
173205 public static function base64ToPEMPublicKey ($ data ) {
174206
175- error_log ("Warning: PluginSession::base64ToPEMPublicKey() is deprecated. Please switch over to SSOToken::base64ToPEMPublicKey(). " );
207+ error_log ("Warning: PluginSession::base64ToPEMPublicKey() is deprecated. Please switch over to SSOToken::base64ToPEMPublicKey(). " );
176208
177209 return SSOToken::base64ToPEMPublicKey ($ data );
178210 }
@@ -260,4 +292,32 @@ public function isUserView() {
260292 return $ this ->userView ;
261293 }
262294
295+ /**
296+ * Destroy the session with the given id
297+ *
298+ * @param String $sessionId
299+ * @return bool true on success or false on failure.
300+ */
301+ public function destroySession (String $ sessionId = null ) {
302+
303+ $ sessionId = $ sessionId ?: $ this ->sessionId ;
304+
305+ // save the current session
306+ $ currentId = session_id ();
307+ session_write_close ();
308+
309+ // switch to the target session and removes it
310+ session_id ($ this ->createCompatibleSessionId ($ sessionId ));
311+ session_start ();
312+ $ result = session_destroy ();
313+
314+ // switches back to the original session
315+ if ($ currentId !== $ sessionId ) {
316+ session_id ($ currentId );
317+ session_start ();
318+ }
319+
320+ return $ result ;
321+ }
322+
263323}
0 commit comments