Skip to content

Commit

Permalink
Authorization tweaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Jan 21, 2024
1 parent a99813b commit 3dcdc64
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 14 deletions.
2 changes: 2 additions & 0 deletions batch/makedist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ NEWS.md
README.md
api.php
assign.php
authorize.php
autoassign.php
bulkassign.php
buzzer.php
Expand Down Expand Up @@ -347,6 +348,7 @@ src/options/o_topics.php
src/pages/p_adminhome.php
src/pages/p_api.php
src/pages/p_assign.php
src/pages/p_authorize.php
src/pages/p_autoassign.php
src/pages/p_bulkassign.php
src/pages/p_buzzer.php
Expand Down
2 changes: 1 addition & 1 deletion etc/pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
[ "signin/form/password", 30, "*Signin_Page::print_signin_form_password" ],
[ "signin/form/actions", 100, "Signin_Page::print_signin_form_actions" ],
[ "signin/form/create", 150, "Signin_Page::print_signin_form_create" ],
[ "signin/form/oauth", 1000, "Signin_Page::print_signin_form_oauth" ],
[ "signin/form/oauth", 1000, "*Signin_Page::print_signin_form_oauth" ],


{ "name": "signout", "allow_disabled": true },
Expand Down
3 changes: 2 additions & 1 deletion src/pages/p_authorize.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
// pages/p_authorize.php -- HotCRP OAuth 2.0 authorization provider page
// Copyright (c) 2022-2023 Eddie Kohler; see LICENSE.
// Copyright (c) 2022-2024 Eddie Kohler; see LICENSE.

class OAuthClient {
/** @var string */
Expand Down Expand Up @@ -151,6 +151,7 @@ private function handle_request(OAuthClient $client) {
Signin_Page::print_form_start_for($this->qreq, "=signin");
$nav = $this->qreq->navigation();
echo Ht::hidden("redirect", "authorize{$nav->php_suffix}?code=" . urlencode($this->token->salt) . "&authconfirm=1");
$this->cs->callable("Signin_Page")->_oauth_hoturl_param = ["quiet" => 1];
$this->cs->print_members("authorize/form");
echo '</div>';
$this->qreq->print_footer();
Expand Down
29 changes: 19 additions & 10 deletions src/pages/p_oauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,14 @@ class OAuth_Page {
public $viewer;
/** @var Qrequest */
public $qreq;
/** @var ?string */
public $site_uri;

function __construct(Contact $viewer, Qrequest $qreq) {
$this->conf = $viewer->conf;
$this->viewer = $viewer;
$this->qreq = $qreq;
$this->site_uri = $qreq->navigation()->base_absolute();
}

function start() {
Expand All @@ -95,6 +98,7 @@ function start() {
$tok->assign_data([
"authtype" => $authi->name,
"session" => $this->qreq->qsid(),
"quiet" => $this->qreq->quiet,
"redirect" => $this->qreq->redirect,
"site_uri" => $this->conf->opt("paperSite"),
"nonce" => $nonce
Expand All @@ -106,7 +110,7 @@ function start() {
. "&redirect_uri=" . rawurlencode($authi->redirect_uri)
. "&state=" . $tok->salt
. "&nonce=" . $nonce;
$this->qreq->set_httponly_cookie("oauth-{$nonce}", "1", Conf::$now + 600);
$this->qreq->set_cookie_opt("oauth-{$nonce}", "1", ["expires" => Conf::$now + 600, "path" => "/", "httponly" => true]);
throw new Redirection(hoturl_add_raw($authi->auth_uri, $params));
} else {
$this->conf->error_msg("<0>Authentication attempt failed");
Expand All @@ -125,7 +129,12 @@ function response() {
return MessageItem::error("<0>OAuth authentication response parameters required");
} else if (!($tok = TokenInfo::find($state, $this->conf, !!$this->conf->contactdb()))) {
return MessageItem::error("<0>Authentication request not found or expired");
} else if (!$tok->is_active()) {
}
$this->site_uri = $tok->data("site_uri") ?? $this->site_uri;
if (!str_ends_with($this->site_uri, "/")) {
$this->site_uri .= "/";
}
if (!$tok->is_active()) {
return MessageItem::error("<0>Authentication request expired");
} else if ($tok->timeUsed) {
return MessageItem::error("<0>Authentication request reused");
Expand All @@ -141,9 +150,10 @@ function response() {
$noncematch = true;
}

if (($tokdata->session ?? "<NO SESSION>") !== $this->qreq->qsid()
|| !$noncematch) {
if (($tokdata->session ?? "<NO SESSION>") !== $this->qreq->qsid()) {
return MessageItem::error("<0>Authentication request ‘{$state}’ was for a different session");
} else if (!$noncematch) {
return MessageItem::error("<0>Authentication request ‘{$state}’ may have been replayed");
} else if (!isset($this->qreq->code)) {
return MessageItem::error("<0>Authentication failed");
} else if (($authi = OAuthProvider::find($this->conf, $tokdata->authtype ?? null))) {
Expand Down Expand Up @@ -239,14 +249,13 @@ private function instance_response($authi, $tok, $tokdata) {
}

$user = $info["user"];
$this->conf->feedback_msg(new MessageItem(null, "<0>Signed in", MessageSet::SUCCESS));
if (!$tokdata->quiet) {
$this->conf->feedback_msg(new MessageItem(null, "<0>Signed in", MessageSet::SUCCESS));
}
$uindex = UpdateSession::user_change($this->qreq, $user->email, true);
UpdateSession::usec_add($this->qreq, $user->email, 1, 0, true);

$uri = $tokdata->site_uri;
if (!str_ends_with($uri, "/")) {
$uri .= "/";
}
$uri = $this->site_uri;
if (count(Contact::session_users($this->qreq)) > 1) {
$uri .= "u/{$uindex}/";
}
Expand All @@ -263,7 +272,7 @@ static function go(Contact $user, Qrequest $qreq) {
$ml = $oap->response();
if ($ml) {
$user->conf->feedback_msg($ml);
throw new Redirection($user->conf->hoturl("signin"));
throw new Redirection($oap->site_uri . "signin" . $qreq->navigation()->php_suffix);
}
} else if ($qreq->valid_post()) {
$oap->start();
Expand Down
8 changes: 6 additions & 2 deletions src/pages/p_signin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class Signin_Page {
public $_reset_token;
/** @var ?Contact */
public $_reset_user;
/** @var ?associative-array<string,mixed> */
public $_oauth_hoturl_param;
/** @var ?MessageSet */
private $_ms;

Expand Down Expand Up @@ -257,15 +259,17 @@ static function print_signin_form_create(Contact $user) {
}
}

static function print_signin_form_oauth(Contact $user, Qrequest $qreq) {
function print_signin_form_oauth(Contact $user, Qrequest $qreq) {
$conf = $user->conf;
if (!$conf->opt("oAuthProviders") && !$conf->opt("oAuthTypes")) {
return;
}
$buttons = [];
$param = array_merge(["authtype" => null], $this->_oauth_hoturl_param ?? ["redirect" => $qreq->redirect]);
foreach ($conf->oauth_providers() as $authdata) {
if ($authdata->button_html && !($authdata->disabled ?? false)) {
$buttons[] = Ht::button($authdata->button_html, ["type" => "submit", "formaction" => $conf->hoturl("=oauth", ["authtype" => $authdata->name, "redirect" => $qreq->redirect]), "formmethod" => "post", "class" => "mt-2 w-100 flex-grow-1"]);
$param["authtype"] = $authdata->name;
$buttons[] = Ht::button($authdata->button_html, ["type" => "submit", "formaction" => $conf->hoturl("=oauth", $param), "formmethod" => "post", "class" => "mt-2 w-100 flex-grow-1"]);
}
}
if (!empty($buttons)) {
Expand Down

0 comments on commit 3dcdc64

Please sign in to comment.