Skip to content
This repository has been archived by the owner on May 14, 2022. It is now read-only.

Add the services module for API support #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 339 additions & 0 deletions openthess/modules/services/LICENSE.txt

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions openthess/modules/services/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

Goals
==============
- Create a unified Drupal API for web services to be exposed in a variety of
different server formats.
- Provide a service browser to be able to test methods.
- Allow distribution of API keys for developer access.

Documentation
==============
http://drupal.org/node/109782

Installation
============
If you are using the rest server you will need to download the latest version of SPYC:
wget https://raw.github.com/mustangostang/spyc/79f61969f63ee77e0d9460bc254a27a671b445f3/spyc.php -O servers/rest_server/lib/spyc.php

Once downloaded you need to add spyc.php to the rest_server/lib folder which exists under
the location you have installed services in.

Documentation files
===================
You can find these files in /docs folder.
services.authentication.api.php -- hooks related to authentication plugins
services.servers.api.php -- servers definition hooks
services.services.api.php -- definition of new services
services.versions.api.php -- how to write versioned resources

Settings via variables
======================

'services_{$resource}_index_page_size' -- this variable controls maximum number of results that
will be displayed by index query. See services_resource_build_index_query() for more information.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.auth-authorization > .fieldset-wrapper > .form-item {
float: left;
margin-right: 20px;
}
206 changes: 206 additions & 0 deletions openthess/modules/services/auth/services_oauth/services_oauth.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<?php

/**
* @file
* Include file for services_oauth module.
*/

/**
* Authenticates a call using OAuth to verify the request.
*
* @param array $settings
* The settings for the authentication module.
* @param array $method
* The method that's being called
* @param array $args
* The arguments that are being used to call the method
* @return void|string
* Returns nothing, or a error message if authentication fails
*/
function _services_oauth_authenticate_call($settings, $method, $args) {
$endpoint = array();
// Grep the specific settings for this method
if (!empty($method['endpoint']['services_oauth']['credentials'])) {
$endpoint += array_filter($method['endpoint']['services_oauth']);
}
$endpoint += $settings;
$cred = isset($endpoint['credentials']) ? $endpoint['credentials'] : 'token';
$auth_level = isset($endpoint['authorization']) ? $endpoint['authorization'] : '*';

// If no credentials are needed we'll pass this one through
if ($cred == 'none') {
return FALSE;
}

try {
module_load_include('inc', 'oauth_common');

list($signed, $consumer, $token) = oauth_common_verify_request();

// if we have no oauth info - pass this one through
if (!$signed && is_null($consumer) && is_null($token)) {
return FALSE;
}
if (!$signed && ($cred == 'consumer' || $cred == 'token')) {
throw new OAuthException('The request must be signed');
}
if ($consumer == NULL) {
throw new OAuthException('Missing consumer token');
}
if ($consumer->context !== $settings['oauth_context']) {
throw new OAuthException('The consumer is not valid in the current context');
}

// Validate the token, if it's required by the method
if ($cred == 'token') {
if (empty($token->key)) {
throw new OAuthException('Missing access token');
}
if (!$token->authorized) {
throw new OAuthException('The access token is not authorized');
}
// Check that the consumer has been granted the required authorization level
if (!empty($auth_level) && !in_array('*', $token->services) && !in_array($auth_level, $token->services)) {
throw new OAuthException('The consumer is not authorized to access this service');
}
}

// Add the oauth authentication info to server info
services_set_server_info('oauth_consumer', $consumer);
services_set_server_info('oauth_token', $token);

// Load the user if the request was authenticated using a token
// that's associated with a account.
if ($cred == 'token') {
if ($token->uid) {
global $user;
$user = user_load($token->uid);
}
}
else if ($cred == 'consumer') {
if ($consumer->uid) {
// This authenticates as the user who owns 'key'; It is for 2-stage
// OAuth and is vastly inferior to 3-stage OAuth.
global $user;
$user = user_load($consumer->uid);
}
}
}
catch (OAuthException $e) {
drupal_add_http_header('WWW-Authenticate', sprintf('OAuth realm="%s"', url('', array('absolute' => TRUE))));
return $e->getMessage();
}
}

function _services_oauth_security_settings_authorization($settings) {
return isset($settings['authorization']) ? $settings['authorization'] : '';
}

function _services_oauth_security_settings($settings, &$form_state) {
if (isset($form_state['values']['services_oauth']['oauth_context'])) {
$settings['oauth_context'] = $form_state['values']['services_oauth']['oauth_context'];
}

$form = array();
$form['oauth_context'] = array(
'#type' => 'select',
'#options' => array('' => t('-- Select an OAuth context')),
'#default_value' => isset($settings['oauth_context']) ? $settings['oauth_context'] : '',
'#title' => t('OAuth context'),
'#description' => t('The OAuth contexts provides a scope for consumers and authorizations and have their own authorization levels. Different services endpoints may share OAuth contexts and thereby allow the use of consumers and tokens across the services endpoint boundraries.'),
);
$form['authorization'] = array(
'#type' => 'select',
'#options' => array(),
'#default_value' => isset($settings['authorization']) ? $settings['authorization'] : '',
'#title' => t('Default required OAuth Authorization level'),
'#description' => t('The default OAuth authorization level that will be required to access resources.'),
);

$contexts = oauth_common_context_load_all();
foreach ($contexts as $context) {
$form['oauth_context']['#options'][$context->name] = $context->title;
if (isset($context->authorization_levels) && $context->name == $settings['oauth_context']) {
foreach ($context->authorization_levels as $name => $level) {
$form['authorization']['#options'][$name] = t($level['title']) . " ({$context->name})";
}
}
}
if (empty($form['authorization']['#options'])) {
$form['authorization'] = array(
'#type' => 'item',
'#title' => t('Select an OAuth context enable default required OAuth Authorization level')
) + $form['authorization'];
}
else {
$form['authorization']['#options'] = array('' => t('None')) + $form['authorization']['#options'];
}

$form['credentials'] = array(
'#type' => 'select',
'#options' => array(
'none' => t('None, OAuth authentication will be disabled by default'),
'unsigned_consumer' => t('Unsigned with consumer key'),
'consumer' => t('Consumer key, also known as 2-legged OAuth'),
'token' => t('Consumer key and access token, also known as 3-legged OAuth'),
),
'#default_value' => $settings['credentials'],
'#title' => t('Default required authentication'),
'#description' => t('Authorization levels will <em>not</em> be applied if the consumer isn\'t required to supply a access token.'),
);

return $form;
}

function _services_oauth_default_security_settings() {
return array(
'oauth_context' => '',
'authorization' => '',
'credentials' => 'token',
);
}

function _services_oauth_controller_settings($settings, $controller, $endpoint, $class, $name) {
$form = array();
$cc = array(
'credentials' => '',
'authorization' => '',
);
if (!empty($controller['endpoint']['services_oauth'])) {
$cc = $controller['endpoint']['services_oauth'] + $cc;
}
$auth_levels = array();
if (is_array($endpoint) && isset($endpoint['oauth_context'])) {
$context = oauth_common_context_load($endpoint['oauth_context']);
if (isset($context->authorization_levels)) {
foreach ($context->authorization_levels as $name => $level) {
$auth_levels[$name] = t($level['title']);
}
}
}

$form['credentials'] = array(
'#type' => 'select',
'#options' => array(
'' => t('Default'),
'none' => t('None'),
'unsigned_consumer' => t('Unsigned with consumer key'),
'consumer' => t('Consumer key'),
'token' => t('Consumer key and access token'),
),
'#default_value' => isset($settings['credentials']) ? $settings['credentials'] : '',
'#title' => t('Required authentication'),
'#description' => t('Authorization levels will <em>not</em> be applied if the consumer isn\'t required to supply a access token.'),
);

$form['authorization'] = array(
'#type' => 'select',
'#options' => array(
'' => t('Default'),
) + $auth_levels,
'#default_value' => isset($settings['authorization']) ? $settings['authorization'] : '',
'#title' => t('Required authorization'),
);

return $form;
}
13 changes: 13 additions & 0 deletions openthess/modules/services/auth/services_oauth/services_oauth.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name = OAuth Authentication
description = Provides OAuth authentication for the services module
package = Services - authentication
dependencies[] = services
dependencies[] = oauth_common
core = 7.x
php = 5.2
; Information added by Drupal.org packaging script on 2014-01-31
version = "7.x-3.7"
core = "7.x"
project = "services"
datestamp = "1391207946"

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/**
* Implements hook_install().
*/
function services_oauth_install() {
drupal_install_schema('services_oauth');
}

/**
* Implements hook_uninstall().
*/
function services_oauth_uninstall() {
drupal_uninstall_schema('services_oauth');
}

/**
* Implements hook_schema().
*/
function services_oauth_schema() {
$schema = array();

return $schema;
}

function services_oauth_update_6001() {
$ret = array();

// Rename the authentication and authorization settings variables
$authentication = variable_get('services_oauth_authentication_levels', array());
$authorization = variable_get('services_oauth_authorization_settings', array());
variable_del('services_oauth_authentication_levels');
variable_del('services_oauth_authorization_settings');
variable_set('services_oauth_authentication_levels_', $authentication);
variable_set('services_oauth_authorization_settings_', $authorization);

return $ret;
}

function services_oauth_update_6200() {
variable_del('services_oauth_authentication_levels_');
variable_del('services_oauth_authorization_settings_');

return array();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* Implementation of hook_services_authentication().
*/
function services_oauth_services_authentication_info() {
return array(
'file' => 'services_oauth.inc',
'title' => t('OAuth authentication'),
'description' => t('An open protocol to allow secure API authorization'),
'security_settings' => '_services_oauth_security_settings',
'default_security_settings' => '_services_oauth_default_security_settings',
'authenticate_call' => '_services_oauth_authenticate_call',
'controller_settings' => '_services_oauth_controller_settings',
);
}
73 changes: 73 additions & 0 deletions openthess/modules/services/css/services.admin.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* Resource Table */
#resource-form-table th.select-all {
width: 1em;
}
th.resource_test {
width: 16em;
}

.resource-image {
display: inline-block;
cursor: pointer;
width: 1em;
}
.resource-group-label label {
display: inline;
font-weight: bold;
}
.resource-test-label label {
margin-left: 1em; /* LTR */
}
.resource-test-description .description {
margin: 0;
}
#resource-form-table tr td {
background-color: white;
color: #494949;
vertical-align: top;
}
#resource-form-table tr.resource-group td {
background-color: #EDF5FA;
color: #494949;
}

#resource-form-table tr.resource-method {
border-bottom: 1px solid #494949;
}

#resource-form-table tr.resource-operation-class {
border-bottom: 2px solid #494949;
border-top: 2px solid #494949;
}


table#resource-form-table tr.resource-group label {
display: inline;
}

div.message > div.item-list {
font-weight: normal;
}
a.resource-collapse {
height: 0;
width: 0;
top: -99em;
position: absolute;
}
a.resource-collapse:focus,
a.resource-collapse:hover {
font-size: 80%;
top: 0px;
height: auto;
width: auto;
overflow: visible;
position: relative;
z-index: 1000;
}
td.resource-group-alias {
width:130px;
}
/* Zebra colors for resources admin table */
#resource-form-table tr.resource-even td {
background: none repeat scroll 0 0 #F3F4EE;
}
Loading