Example #1
0
function Users_authorize_post()
{
    if (empty($_REQUEST['authorize'])) {
        return null;
    }
    // If we are here, the logged-in user requested to authorize the client
    $terms_uri = Q_Config::get('Users', 'authorize', 'terms', 'uri', null);
    $terms_label = Q_Config::get('Users', 'authorize', 'terms', 'label', null);
    $terms_title = Q_Config::get('Users', 'authorize', 'terms', 'title', null);
    if ($terms_uri and $terms_title and $terms_label) {
        if (empty($_REQUEST['agree'])) {
            throw new Q_Exception("First you must agree to the {$terms_title}", 'agree');
        }
    }
    $user = Users::loggedInUser(true);
    $client_id = $_REQUEST['client_id'];
    $redirect_url = $_REQUEST['redirect_uri'];
    $state = $_REQUEST['state'];
    // for now we ignore the scope requested and always authorize "user"
    $oa = new Users_OAuth();
    $oa->client_id = $client_id;
    $oa->userId = $user->id;
    $oa->state = $state;
    if ($oa->retrieve()) {
        if ($oa->scope !== 'user' || $oa->redirect_uri !== $redirect_url) {
            throw new Q_Exception("Different parameters were requested with the same state string before", 'state');
        }
        Users::$cache['oAuth'] = $oa;
        return;
    }
    $duration_name = Q_Config::expect('Users', 'authorize', 'duration');
    $duration = Q_Config::expect('Q', 'session', 'durations', $duration_name);
    $access_token = Users::copyToNewSession($duration);
    $oa->scope = 'user';
    // for now the scope of authorization is always "user"
    $oa->redirect_uri = $redirect_url;
    // just saving it
    $oa->access_token = $access_token;
    // the session token
    $oa->token_expires_seconds = $duration;
    // session actually expires after $duration seconds of inactivity
    $oa->save();
    Q::event('Users/authorize/success', array('oAuth' => $oa, 'duration' => $duration), 'after');
    Users::$cache['oAuth'] = $oa;
}
Example #2
0
/**
 * We are going to implement a subset of the OAuth 1.0a functionality for now,
 * and later we can expand it to match the full OAuth specification.
 */
function Users_authorize_response()
{
    if (Q_Response::getErrors()) {
        Q_Dispatcher::showErrors();
    }
    $client_id = $_REQUEST['client_id'];
    $redirect_url = $_REQUEST['redirect_uri'];
    $state = $_REQUEST['state'];
    $client = Users_User::fetch($client_id);
    if (!$client) {
        throw new Q_Exception_MissingRow(array('table' => 'user', 'criteria' => "id = '{$client_id}'"), 'client_id');
    }
    if (empty($client->url)) {
        throw new Q_Exception("Client app needs to register url", 'client_id');
    }
    if (substr($redirect_url, 0, strlen($client->url)) !== $client->url) {
        throw new Q_Exception_WrongValue(array('field' => 'redirect_uri', 'range' => "a url prefixed by client user's url"));
    }
    $user = Users::loggedInUser();
    $oa = null;
    if (isset(Users::$cache['oAuth'])) {
        $oa = Users::$cache['oAuth'];
    } else {
        if ($user) {
            $oa = new Users_OAuth();
            $oa->client_id = $client_id;
            $oa->userId = $user->id;
            $oa->state = $state;
            $oa->retrieve();
        }
    }
    if ($oa and $oa->wasRetrieved()) {
        // User is logged in and already has a token for this client_id and state
        $separator = strpos($redirect_url, '?') === false ? '?' : '&';
        $url = $redirect_url . $separator . http_build_query(array('access_token' => $oa->access_token, 'token_type' => 'bearer', 'expires_in' => $oa->token_expires_seconds, 'scope' => 'user', 'state' => $oa->state));
        Q_Response::redirect(Q_Uri::from($url, false));
        return false;
    }
    $terms_label = Users::termsLabel('authorize');
    $content = Q::view('Users/content/authorize.php', compact('client', 'redirect_url', 'user', 'state', 'terms_label'));
    Q_Response::setSlot('content', $content);
    Q_Response::setSlot('column0', $content);
    return true;
}
Example #3
0
/**
 * We are going to implement a subset of the OAuth 1.0a functionality for now,
 * and later we can expand it to match the full OAuth specification.
 */
function Users_authorize_response()
{
    if (Q_Response::getErrors()) {
        Q_Dispatcher::showErrors();
    }
    $response_type = 'token';
    $token_type = 'bearer';
    $client_id = $_REQUEST['client_id'];
    $state = $_REQUEST['state'];
    $skip = Q::ifset($_REQUEST, 'skip', false);
    $scope = Users_OAuth::requestedScope(true, $scopes);
    $client = Users_User::fetch($client_id, true);
    if (!$client) {
        throw new Q_Exception_MissingRow(array('table' => 'client user', 'criteria' => "id = '{$client_id}'"), 'client_id');
    }
    if (empty($client->url)) {
        throw new Q_Exception("Client app needs to register url", 'client_id');
    }
    $redirect_uri = Q::ifset($_REQUEST, 'redirect_uri', $client->url);
    $user = Users::loggedInUser();
    $oa = null;
    if (isset(Users::$cache['oAuth'])) {
        $oa = Users::$cache['oAuth'];
    } else {
        if ($user) {
            $oa = new Users_OAuth();
            $oa->client_id = $client_id;
            $oa->userId = $user->id;
            $oa->state = $state;
            $oa = $oa->retrieve();
        }
    }
    $remaining = $scope;
    if ($oa and $oa->wasRetrieved()) {
        // User is logged in and already has a token for this client_id and state
        $paths = Q_Config::get('Users', 'authorize', 'clients', Q::app(), 'redirectPaths', false);
        $path = substr($redirect_uri, strlen($client->url) + 1);
        $p = array('response_type' => $response_type, 'token_type' => $token_type, 'access_token' => $oa->access_token, 'expires_in' => $oa->token_expires_seconds, 'scope' => implode(' ', $scope), 'state' => $oa->state);
        $p = Q_Utils::sign($p, 'Q.Users.oAuth');
        // the redirect uri could be a native app url scheme
        $s = strpos($redirect_uri, '#') === false ? '#' : '&';
        $redirect_uri = Q_Uri::from($redirect_uri . $s . http_build_query($p), false)->toUrl();
        if (!Q::startsWith($redirect_uri, $client->url) or is_array($paths) and !in_array($path, $paths)) {
            throw new Users_Exception_Redirect(array('uri' => $redirect_uri));
        }
        Q_Response::redirect($redirect_uri);
        return false;
    }
    $terms_label = Users::termsLabel('authorize');
    Q_Response::setScriptData('Q.Users.authorize', compact('client_id', 'redirect_uri', 'scope', 'scopes', 'remaining', 'state', 'response_type', 'skip'));
    $content = Q::view('Users/content/authorize.php', compact('client', 'user', 'redirect_uri', 'scope', 'scopes', 'remaining', 'state', 'terms_label', 'response_type', 'skip'));
    Q_Response::setSlot('content', $content);
    Q_Response::setSlot('column0', $content);
    return true;
}