+ // We check that the return url matches a per-key regexp to prevent
+ // replay attacks (more exactly to force replay attacks to redirect
+ // the user to the real GroupeX website, which defeats the attack).
+ if (empty($returnurls) || @preg_match($returnurls, $ext_url)) {
+ $returl = $ext_url . gpex_make_params($gpex_challenge, $privkey, $datafields, $charset);
+ XDB::execute('UPDATE group_auth
+ SET last_used = DATE(NOW())
+ WHERE name = {?}',
+ $name);
+
+ // Two conditions control access to the return URL:
+ // - If that URL is attached to a group:
+ // - If the user belongs to the group, OK
+ // - If the user is 'xnet' and doesn't belong, NOK
+ // - If the user is not 'xnet' and the group is not 'strict', OK
+ // - If the user is not 'xnet' and the group is 'strict', NOK
+ // - Otherwise, all but 'xnet' accounts may access the URL.
+ $user_is_xnet = S::user()->type == 'xnet';
+ $group_flags = new PlFlagSet($group_flags);
+
+ // If this key is not attached to a group, but a group was
+ // requested (e.g query from wiki / blogs / ...), use the
+ // requested group_id.
+ if (!$group_id && $req_group_id) {
+ $group_id = $req_group_id;
+ }
+
+ if ($group_id) {
+ // Check group permissions
+ $is_member = XDB::fetchOneCell('SELECT COUNT(*)
+ FROM group_members
+ WHERE uid = {?} AND asso_id = {?}',
+ S::user()->id(), $group_id);
+ if (!$is_member && ($user_is_xnet || $group_flags->hasFlag('group_only'))) {
+ $page->kill("Le site demandé est réservé aux membres du groupe $group_name.");
+ }
+
+ } else if ($user_is_xnet && !$group_flags->hasFlag('allow_xnet')) {
+ $page->kill("Le site demandé est réservé aux polytechniciens.");
+ }
+
+ // If we logged in specifically for this 'external_auth' request
+ // and didn't want to "keep access to services", we kill the session
+ // just before returning.
+ // See classes/xorgsession.php:startSessionAs
+ if (S::b('external_auth_exit')) {
+ S::logger()->log('decconnexion', @$_SERVER['HTTP_REFERER']);
+ Platal::session()->killAccessCookie();
+ Platal::session()->destroy();
+ }