123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <?php
- /**
- * Combined menu callback for tests of consumers and access tokens
- */
- function _oauth_common_validate_request_callback($type, $unsigned = NULL) {
- try {
- module_load_include('inc', 'oauth_common');
- list($signed, $consumer, $token) = oauth_common_verify_request();
- if ($consumer == NULL) {
- throw new OAuthException('Missing consumer token');
- }
- if (!$signed && $unsigned != 'unsigned') {
- throw new OAuthException("The request wasn't signed");
- }
- if ($token == NULL && $type == 'access token') {
- throw new OAuthException('Missing access token');
- }
- }
- catch (OAuthException $e) {
- drupal_add_http_header('Status', '401 Unauthorized: ' . $e->getMessage());
- drupal_add_http_header('WWW-Authenticate', sprintf('OAuth realm="%s"', url('', array('absolute' => TRUE))));
- }
- exit;
- }
- /**
- * Menu callback for when something has been authorized - used in both client and provider flow
- *
- * @param $csid Should contain the id of the consumer when used in the client flow
- */
- function oauth_common_page_authorized($csid = NULL) {
- // If we have an oauth_token we're acting as a consumer and just got authorized
- if (!empty($_GET['oauth_token'])) {
- //TODO: Add documentation on how to use the callback url with
- $consumer = $csid ? DrupalOAuthConsumer::loadById($csid, FALSE) : FALSE;
- if ($consumer) {
- $request_token = DrupalOAuthToken::loadByKey($_GET['oauth_token'], $consumer, OAUTH_COMMON_TOKEN_TYPE_REQUEST);
- }
- else {
- // Backwards compatibility with 6.x-3.0-beta3
- $request_token = DrupalOAuthToken::load($_GET['oauth_token'], FALSE);
- $consumer = $request_token ? $request_token->consumer : FALSE;
- }
- if (!empty($request_token)) {
- $client = new DrupalOAuthClient($consumer, $request_token);
- $verifier = isset($_GET['oauth_verifier']) ? $_GET['oauth_verifier'] : NULL;
- $access_token = $client->getAccessToken(NULL, array('verifier' => $verifier));
- if ($access_token) {
- // We recieved a new token - save it
- if (!$access_token->in_database) {
- $access_token->write();
- }
- $request_token->delete();
- module_invoke_all('oauth_common_authorized', $consumer, $access_token, $request_token);
- }
- }
- }
- return t('The application has been authorized');
- }
- /**
- * Form for granting access to the consumer
- */
- function oauth_common_form_authorize() {
- module_load_include('inc', 'oauth_common');
- $req = DrupalOAuthRequest::from_request();
- $context = oauth_common_context_from_request($req);
- $auth_ops = $context->authorization_options;
-
- if (!$context) {
- drupal_set_message(t("Can't find OAuth context, check the site's settings."), 'error');
- return;
- }
- $token = $req->get_parameter('oauth_token');
- $callback = $req->get_parameter('oauth_callback');
- $token = DrupalOAuthToken::loadByKey($token, FALSE, OAUTH_COMMON_TOKEN_TYPE_REQUEST);
- // Check that we have a valid token
- if (!$token) {
- drupal_set_message(t('Please include a valid OAuth token in your request.'), 'error');
- return;
- }
- $consumer = $token->consumer;
- // Redirect to the right form, or present an error.
- global $user;
- if ($user->uid) {
- // There's some strange bug in the ?destination=... handling
- // This is not exactly beautiful, but it gets the work done
- // TODO: Find out why!
- if (drupal_substr($_SERVER['REQUEST_URI'], 0, 2) == '//') {
- header('Location: ' . drupal_substr($_SERVER['REQUEST_URI'], 1), TRUE, 302);
- }
- if (!(user_access('oauth authorize any consumers') || user_access('oauth authorize consumers in ' . $consumer->context))) {
- drupal_set_message(t('You are not authorized to allow external services access to this system.'), 'error');
- return drupal_access_denied();
- }
-
- if (!empty($auth_ops['automatic_authorization'])
- && $auth_ops['automatic_authorization']
- && !empty($consumer->callback_url)) {
- // Authorize the request token
- $token->uid = $user->uid;
- $token->authorized = 1;
- $token->services = $context->authorization_options['default_authorization_levels'];
- $token->write(TRUE);
- // Pick the callback url apart and add the token parameter
- $callback = parse_url($consumer->callback_url);
- $query = array();
- parse_str($callback['query'], $query);
- $query['oauth_token'] = $token->key;
- $callback['query'] = http_build_query($query, 'idx_', '&');
- // Return to the consumer site
- header('Location: ' . _oauth_common_glue_url($callback), TRUE, 302);
- exit;
- }
- $tvars = array(
- '@user' => $user->name,
- '@appname' => $consumer->name,
- '@sitename' => variable_get('site_name', ''),
- );
- $title = !empty($context->title) ? $context->title : 'Authorize @appname';
- drupal_set_title(t($title, $tvars), PASS_THROUGH);
- $form = array();
- $form['token'] = array(
- '#type' => 'value',
- '#value' => $token,
- );
- $message = !empty($auth_ops['message']) ? $auth_ops['message'] :
- 'The application @appname wants to access @sitename on your behalf, check the permissions that you would like the application to have.';
- $form['message'] = array(
- '#type' => 'item',
- '#markup' => t($message, $tvars),
- );
- $message = !empty($auth_ops['warning']) ? $auth_ops['warning'] :
- 'If you don\'t know what @appname is, or don\'t want to give it access to your content, just click here and we\'ll take you away from this page without granting @appname any access to @sitename.';
- $form['warning'] = array(
- '#type' => 'item',
- '#markup' => l(t($message, $tvars), 'oauth/authorization/deny/' . $token->key),
- '#attributes' => array(
- 'class' => array('abort-authorization'),
- ),
- );
- $disable_selection = !empty($auth_ops['disable_auth_level_selection'])
- && !empty($auth_ops['default_authorization_levels'])
- && $auth_ops['disable_auth_level_selection'];
- if (!$disable_selection) {
- $authorization_title = !empty($auth_ops['authorization_title']) ? $auth_ops['authorization_title'] :
- 'Permissions';
- $form['authorization'] = array(
- '#type' => 'fieldset',
- '#title' => t($authorization_title, $tvars),
- );
- $form['authorization']['levels'] = array(
- '#tree' => TRUE,
- );
- foreach ($context->authorization_levels as $name => $level) {
- $auth_level_opt = array(
- '#type' => 'checkbox',
- '#title' => t($level['title'], $tvars),
- '#description' => t($level['description'], $tvars),
- '#value' => $level['default'],
- );
- $form['authorization']['levels'][$name] = $auth_level_opt;
- }
- }
- else {
- $form['authorization']['levels'] = array(
- '#tree' => TRUE,
- );
- foreach ($auth_ops['default_authorization_levels'] as $level) {
- $form['authorization']['levels'][$level] = array(
- '#type' => 'value',
- '#value' => $level,
- );
- }
- }
- $deny_title = !empty($auth_ops['deny_access_title']) ? $auth_ops['deny_access_title'] :
- 'Deny access';
- $form['deny'] = array(
- '#type' => 'item',
- '#markup' => l(t($deny_title), 'oauth/authorization/deny/' . $token->key),
- '#attributes' => array(
- 'class' => array('deny-access'),
- ),
- );
- $grant_title = !empty($auth_ops['grant_access_title']) ? $auth_ops['grant_access_title'] :
- 'Grant access';
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['confirm'] = array(
- '#type' => 'submit',
- '#value' => t($grant_title),
- );
- return $form;
- }
- else {
- $query = $_GET;
- unset($query['q']); // why are there so few q's?
- drupal_goto('user/login', array('query' => array(
- 'destination' => url('oauth/authorize', array(
- 'query' => $query,
- )),
- )));
- }
- }
- /**
- * Validation of the form for granting access to the consumer
- */
- function oauth_common_form_authorize_validate($form, &$form_state) {
- $values = $form_state['values'];
- $got_permission = FALSE;
- $consumer = $values['token']->consumer;
- $context = oauth_common_context_load($consumer->context);
- if (!$context) {
- form_set_error('confirm', t("Can't find OAuth context."));
- return;
- }
- if (!$context->authorization_options['disable_auth_level_selection']) {
- foreach ($context->authorization_levels as $name => $level) {
- if ($values['levels'][$name]) {
- $got_permission = TRUE;
- break;
- }
- }
- if (!$got_permission) {
- form_set_error('confirm', t("You haven't given the application access to anything. Click on 'Deny access' or just close this window if you don't want to authorize it."));
- }
- }
- }
- /**
- * Form submit handler that grants access to the consumer
- */
- function oauth_common_form_authorize_submit(&$form, &$form_state) {
- global $user;
- $values = $form_state['values'];
- // Save the list of all services that the user allowed the
- // consumer to do
- $token = $values['token'];
- $token->uid = $user->uid;
- $token->authorized = 1;
- $consumer = $token->consumer;
- $context = oauth_common_context_load($consumer->context);
- if (!$context) {
- drupal_set_message(t("Can't find OAuth context, check the site's settings."), 'error');
- return;
- }
- // Add services
- if (!empty($values['full_access'])) { // TODO: Full access should be a configurable auth level
- $token->services = array('*');
- }
- elseif (!empty($values['levels'])) {
- $token->services = array_keys(array_filter($values['levels']));
- }
- else {
- $token->services = array();
- }
- $token->write(TRUE);
- if (!empty($consumer->callback_url) && $consumer->callback_url !== 'oob') {
- // Pick the callback url apart and add the token parameter
- $callback = parse_url($consumer->callback_url);
- $query = array();
- if (!empty($callback['query'])) {
- parse_str($callback['query'], $query);
- }
- $query['oauth_token'] = $token->key;
- $callback['query'] = http_build_query($query, 'idx_', '&');
- // Return to the consumer site
- header('Location: ' . _oauth_common_glue_url($callback), TRUE, 302);
- exit;
- }
- else {
- drupal_goto('oauth/authorized');
- }
- }
- /**
- * Constructs the url to which to return someone who has asked for access to a consumer
- */
- function _oauth_common_glue_url($parsed) {
- $uri = isset($parsed['scheme']) ? $parsed['scheme'] . '://' : '';
- $uri .= isset($parsed['user']) ? $parsed['user'] . (isset($parsed['pass']) ? ':' . $parsed['pass'] : '') . '@' : '';
- $uri .= isset($parsed['host']) ? $parsed['host'] : '';
- $uri .= isset($parsed['port']) ? ':' . $parsed['port'] : '';
- if (isset($parsed['path'])) {
- $uri .= (substr($parsed['path'], 0, 1) == '/') ?
- $parsed['path'] :
- ((!empty($uri) ? '/' : '' ) . $parsed['path']);
- }
- $uri .= isset($parsed['query']) ? '?' . $parsed['query'] : '';
- return $uri;
- }
- /**
- * Generate a request token from the request.
- */
- function oauth_common_callback_request_token() {
- try {
- $req = DrupalOAuthRequest::from_request();
- $context = oauth_common_context_from_request($req);
- if (!$context) {
- throw new OAuthException('No OAuth context found');
- }
- $server = new DrupalOAuthServer($context);
- print $server->fetch_request_token($req);
- }
- catch (OAuthException $e) {
- drupal_add_http_header('Status', '401 Unauthorized: ' . $e->getMessage());
- drupal_add_http_header('WWW-Authenticate', sprintf('OAuth realm="%s"', url('', array('absolute' => TRUE))));
- }
- }
- /**
- * Get a access token for the request
- */
- function oauth_common_callback_access_token() {
- try {
- $req = DrupalOAuthRequest::from_request();
- $context = oauth_common_context_from_request($req);
- if (!$context) {
- throw new OAuthException('No OAuth context found');
- }
- $server = new DrupalOAuthServer($context);
- $access_token = $server->fetch_access_token($req);
- // Set the expiry time based on context settings or get parameter
- $expires = !empty($context->authorization_options['access_token_lifetime']) ? REQUEST_TIME + $context->authorization_options['access_token_lifetime'] : 0;
- if ($_GET['expires'] && intval($_GET['expires'])) {
- $hint = intval($_GET['expires']);
- // Only accept more restrictive expiry times
- if ($expires == 0 || $hint < $expires) {
- $expires = $hint;
- }
- }
- // Store the expiry time if the access token should expire
- if ($expires) {
- $access_token->expires = $expires;
- $access_token->write(TRUE);
- }
- print $access_token;
- }
- catch (OAuthException $e) {
- drupal_add_http_header('Status', '401 Unauthorized: ' . $e->getMessage());
- drupal_add_http_header('WWW-Authenticate', sprintf('OAuth realm="%s"', url('', array('absolute' => TRUE))));
- }
- }
|