X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=modules%2Fopenid%2Fopenid.inc.php;h=0e0caa1c5a3ffb47c7c9c4e16756b0f9fc5643d5;hb=ad9285e2f0ef7fe27e3801b603061ba33eedeb2b;hp=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391;hpb=b69727b412cae8449a78dee9ec79ddc70aab985f;p=platal.git diff --git a/modules/openid/openid.inc.php b/modules/openid/openid.inc.php index e69de29..0e0caa1 100644 --- a/modules/openid/openid.inc.php +++ b/modules/openid/openid.inc.php @@ -0,0 +1,256 @@ +base_url = $globals->baseurl . '/openid'; + $this->spool_store = $globals->spoolroot . '/spool/openid/store'; + } + + // Initializes an OpenId Server object; it will use a defined spool-based + // directory to store OpenID secrets. Returns true on success. + public function Initialize() + { + require_once 'Auth/OpenID/FileStore.php'; + require_once 'Auth/OpenID/Server.php'; + + $store = new Auth_OpenID_FileStore($this->spool_store); + $this->server = new Auth_OpenID_Server($store, $this->base_url); + $this->request = $this->server->decodeRequest(); + + return !is_a($this->request, 'Auth_OpenID_ServerError'); + } + + // Authorization logic helpers --------------------------------------------- + + // Returns true iff the current request is a valid openid request. + public function IsOpenIdRequest() + { + return Env::has('openid_mode'); + } + + // Returns true iff the request needs to be handled directly by the calling + // code (ie. the current user needs to be authorized). + public function IsAuthorizationRequest() + { + return $this->request->mode == 'checkid_immediate' || + $this->request->mode == 'checkid_setup'; + } + + // Returns true iff the request requires an immediate answer (no user + // interaction is allowed). + public function IsImmediateRequest() + { + return $this->request->mode == 'checkid_immediate'; + } + + // Returns true iff the logged-in user is authorized for the current request. + // It checks that the user is logged in, and has the authorization to use + // that identity. + public function IsUserAuthorized(User $user) + { + return $user && ($user->login() == $this->request->identity || + $this->request->idSelect()); + } + + // SimpleRegistration helpers ---------------------------------------------- + + // Determines which SREG data are requested by the endpoint, and returns them. + public function GetSRegDataForRequest(User &$user) + { + require_once 'Auth/OpenID/SReg.php'; + + // Other common SReg fields we could fill are: + // dob, country, language, timezone. + $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($this->request); + return Auth_OpenID_SRegResponse::extractResponse($sreg_request, array( + 'fullname' => $user->fullName(), + 'nickname' => $user->displayName(), + 'email' => $user->bestEmail(), + 'gender' => $user->isFemale() ? 'F' : 'M', + )); + } + + // Handling and answering helpers ------------------------------------------ + + // Answers the current request, and renders the response. Appends the |sreg| + // data when not null. + public function AnswerRequest($is_authorized, $sreg_data = null) + { + // Creates the response. + if ($is_authorized && $this->request->idSelect()) { + $user = S::user(); + $response = $this->request->answer( + $is_authorized, null, $user->login(), $this->GetUserUrl($user)); + } else { + $response = $this->request->answer($is_authorized); + } + + // Clobbers response, and get it back to the Relaying Party. + if ($sreg_data) { + $sreg_data->toMessage($response->fields); + } + $this->RenderResponse($response); + } + + // Automatically handles the request without any user interaction. + public function HandleRequest() + { + $response = $this->server->handleRequest($this->request); + $this->RenderResponse($response); + } + + // Trust management helpers ------------------------------------------------ + + // Returns true iff the current endpoint is currently trusted by |user|. + public function IsEndpointTrusted(User $user) + { + $res = XDB::query( + "SELECT COUNT(*) + FROM account_auth_openid + WHERE (uid = {?} OR uid IS NULL) AND url = {?}", + $user->id(), $this->request->trust_root); + return ($res->fetchOneCell() > 0); + } + + // Updates the trust level for the given endpoint, based on the value pf + // |trusted| and |permanent_trust| (the latter is ignored when the former + // value is false). Returns true iff the current endpoint is trusted. + public function UpdateEndpointTrust(User &$user, $trusted, $permanent_trust) { + $initial_trust = $this->IsEndpointTrusted($user); + if (!$initial_trust && $trusted && $permanent_trust) { + XDB::execute( + "INSERT IGNORE INTO account_auth_openid + SET uid = {?}, url = {?}", + $user->id(), $this->request->trust_root); + } + + return ($initial_trust || $trusted); + } + + // Page renderers ---------------------------------------------------------- + + // Renders the OpenId discovery page for |user|. + public function RenderDiscoveryPage(&$page, User &$user) + { + $page->changeTpl('openid/openid.tpl'); + $page->setTitle($user->fullName()); + $page->addLink('openid.server openid2.provider', $this->base_url); + $page->addLink('openid.delegate openid2.local_id', $user->login()); + $page->assign_by_ref('user', $user); + + // Include the X-XRDS-Location header for Yadis discovery. + header('X-XRDS-Location: ' . $this->GetUserXrdsUrl($user)); + } + + // Renders the main XRDS page. + public function RenderMainXrdsPage(&$page) + { + pl_content_headers("application/xrds+xml"); + $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN); + $page->assign('type2', Auth_OpenID_TYPE_2_0_IDP); + $page->assign('sreg', Auth_OpenID_SREG_URI); + $page->assign('provider', $this->base_url); + } + + // Renders the XRDS page of |user|. + public function RenderUserXrdsPage(&$page, User &$user) + { + pl_content_headers("application/xrds+xml"); + $page->changeTpl('openid/user_xrds.tpl', NO_SKIN); + $page->assign('type2', Auth_OpenID_TYPE_2_0); + $page->assign('type1', Auth_OpenID_TYPE_1_1); + $page->assign('sreg', Auth_OpenID_SREG_URI); + $page->assign('provider', $this->base_url); + $page->assign('local_id', $user->login()); + } + + // Renders the OpenId response for the HTTP client. + public function RenderResponse($response) + { + if ($response) { + $web_response = $this->server->encodeResponse($response); + header(sprintf('%s %d', $_SERVER['SERVER_PROTOCOL'], $web_response->code), + true, $web_response->code); + + if (is_a($response, 'Auth_OpenID_ServerError')) { + print "Erreur lors de l'authentification OpenId: " . $response->toString(); + } else { + foreach ($web_response->headers as $key => $value) { + header(sprintf('%s: %s', $key, $value)); + } + + header('Connection: close'); + print $web_response->body; + } + } + exit; + } + + // URL providers ----------------------------------------------------------- + + // Returns the OpenId identity URL of the requested user. + private function GetUserUrl(User &$user) + { + return $this->base_url . '/' . $user->login(); + } + + // Returns the private XRDS page of a user. + private function GetUserXrdsUrl(User &$user) + { + return $this->base_url . '/xrds/' . $user->login(); + } + + // Returns the endpoint in the current request. + public function GetEndpoint() + { + return $this->request->trust_root; + } + + // Extracts the OpenId arguments available in the current request, and + // builds a query string with them. + public function GetQueryStringForRequest() + { + foreach (Auth_OpenID::getQuery() as $key => $value) { + if (strpos($key, 'openid.') === 0) { + $args[$key] = $value; + } + } + + return http_build_query($args); + } +} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?>