You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by mf...@apache.org on 2014/08/29 14:16:58 UTC
[34/50] [abbrv] git commit: Modularizes API.
Modularizes API.
Project: http://git-wip-us.apache.org/repos/asf/rave/repo
Commit: http://git-wip-us.apache.org/repos/asf/rave/commit/fa312487
Tree: http://git-wip-us.apache.org/repos/asf/rave/tree/fa312487
Diff: http://git-wip-us.apache.org/repos/asf/rave/diff/fa312487
Branch: refs/heads/angular
Commit: fa31248756c8b43dc796310404e27d6d331cbde5
Parents: 20b522c
Author: Jmeas <je...@gmail.com>
Authored: Mon Aug 18 15:01:10 2014 -0400
Committer: Jmeas <je...@gmail.com>
Committed: Mon Aug 18 15:18:25 2014 -0400
----------------------------------------------------------------------
.jshintrc-mock-api | 1 -
rave-portal-ng/mock-api/bootstrap.js | 3 +-
rave-portal-ng/mock-api/core.js | 37 ++++++++
.../mock-api/modules/preferences/db.js | 52 ++++++++++++
.../mock-api/modules/preferences/endpoint.js | 28 +++++++
.../mock-api/modules/preferences/get.js | 32 -------
.../mock-api/modules/preferences/index.js | 14 ++++
.../mock-api/modules/preferences/put.js | 56 -------------
rave-portal-ng/mock-api/modules/user/db.js | 54 ++++++++++++
rave-portal-ng/mock-api/util/endpoint.js | 88 ++++++++++++++++++++
rave-portal-ng/mock-api/util/error-response.js | 15 ++++
rave-portal-ng/mock-api/util/params.js | 37 ++++++++
rave-portal-ng/mock-api/util/token-util.js | 30 +++++++
13 files changed, 356 insertions(+), 91 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/.jshintrc-mock-api
----------------------------------------------------------------------
diff --git a/.jshintrc-mock-api b/.jshintrc-mock-api
index 754b84c..499a280 100644
--- a/.jshintrc-mock-api
+++ b/.jshintrc-mock-api
@@ -29,7 +29,6 @@
"unused" : "vars",
"strict" : false,
"trailing" : true,
- "maxparams" : 4,
"maxdepth" : 2,
"asi" : false,
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/bootstrap.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/bootstrap.js b/rave-portal-ng/mock-api/bootstrap.js
index 71e344b..92db321 100644
--- a/rave-portal-ng/mock-api/bootstrap.js
+++ b/rave-portal-ng/mock-api/bootstrap.js
@@ -37,8 +37,7 @@ define(function(require) {
require('./modules/category/delete.js');
// preferences
- require('./modules/preferences/get.js');
- require('./modules/preferences/put.js');
+ require('./modules/preferences/index');
// users
require('./modules/users/get.js');
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/core.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/core.js b/rave-portal-ng/mock-api/core.js
index 780c32d..f782a7c 100644
--- a/rave-portal-ng/mock-api/core.js
+++ b/rave-portal-ng/mock-api/core.js
@@ -145,6 +145,42 @@ define(function(require) {
return true;
}
+ // Parse an endpoint for registration with the mock API. Eventually,
+ // this should be the only thing that's in the core.
+ function registerEndpoint(endpoint) {
+
+ // Get our callback and url from the endpoint
+ var callback = endpoint.callback;
+ var url = endpoint.url;
+
+ // The endpoint methods that we will register
+ var methods = ['get', 'put', 'post', 'delete'];
+
+ // Register each method
+ _.each(methods, function(method) {
+ if (endpoint[method]) {
+ registerEndpointCallback(endpoint, url, method, callback);
+ }
+ });
+ }
+
+ // Once the endpoint has been parsed, we actually make the registration here
+ function registerEndpointCallback(endpoint, route, method, callback) {
+ if (!registeredApiMethods.hasOwnProperty(route)) {
+ registeredApiMethods[route] = {
+ pattern: convertRouteToRegex(baseApiUrl+route),
+ methods: {}
+ };
+ }
+
+ // Bind the callback to the endpoint
+ var moddedCallback = function(method, url, data, headers) {
+ return callback.bind(endpoint)(method, url, data, headers);
+ };
+
+ registeredApiMethods[route].methods[method.toUpperCase()] = moddedCallback;
+ }
+
function setSessionStorage(key, value) {
try {
value = JSON.stringify(value);
@@ -171,6 +207,7 @@ define(function(require) {
return {
initialize: initializeApiModule,
register: registerApiMethod,
+ registerEndpoint: registerEndpoint,
db: database,
session: {
set: setSessionStorage,
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/modules/preferences/db.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/modules/preferences/db.js b/rave-portal-ng/mock-api/modules/preferences/db.js
new file mode 100644
index 0000000..9d26997
--- /dev/null
+++ b/rave-portal-ng/mock-api/modules/preferences/db.js
@@ -0,0 +1,52 @@
+/*
+ * db
+ * Methods for getting and setting preferences data. Anytime
+ * you need to hit the DB in reference to preferences it should
+ * go through this file.
+ *
+ */
+
+define(function(require) {
+ var api = require('../../core.js');
+
+ var prefsDb = {
+
+ // Retrieve all of your preferences from the database.
+ // Although they're stored in the DB an array of objects with two
+ // properties each, key and value, this method transforms that data into an object.
+ get: function() {
+ var results = api.db.query('preferences');
+ var preferences = {};
+
+ _.each(results, function(item) {
+ preferences[item.key] = item.value;
+ });
+
+ return preferences;
+ },
+
+ // Update the data in the database
+ put: function(data) {
+ var searchParams;
+
+ // Loop through each value, updating it in the database
+ _.each(data, function(value, key) {
+ searchParams = {
+ key: key
+ };
+ api.db.update('preferences', searchParams, function(row) {
+ row.value = value;
+ return row;
+ });
+ });
+
+ // Save our data
+ api.db.commit();
+
+ // Lastly, return the updated data
+ return prefsDb.get();
+ }
+ };
+
+ return prefsDb;
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/modules/preferences/endpoint.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/modules/preferences/endpoint.js b/rave-portal-ng/mock-api/modules/preferences/endpoint.js
new file mode 100644
index 0000000..3696557
--- /dev/null
+++ b/rave-portal-ng/mock-api/modules/preferences/endpoint.js
@@ -0,0 +1,28 @@
+/*
+ * endpoint
+ * The actual endpoint for preferences
+ *
+ */
+
+define(function(require) {
+ var Endpoint = require('../../util/endpoint');
+ var prefsDb = require('./db');
+
+ var endpoint = new Endpoint({
+
+ url: '/preferences',
+
+ // Our get endpoint. All that it does is return our
+ // of preferences as a simple object.
+ get: function(url, data, headers, params, currentUser) {
+ return [200, prefsDb.get()];
+ },
+
+ // Puts our data into the database.
+ put: function(url, data, headers, params, currentUser) {
+ return [200, prefsDb.put(data)];
+ }
+ });
+
+ return endpoint;
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/modules/preferences/get.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/modules/preferences/get.js b/rave-portal-ng/mock-api/modules/preferences/get.js
deleted file mode 100644
index 4928b37..0000000
--- a/rave-portal-ng/mock-api/modules/preferences/get.js
+++ /dev/null
@@ -1,32 +0,0 @@
-define(function(require) {
- 'use strict';
-
- var api = require('../../core.js');
- require('underscore/underscore');
-
- function getPreferences() {
- var results = api.db.query('preferences');
- var preferences = {};
-
- _.each(results, function(item) {
- preferences[item.key] = item.value;
- });
-
- return preferences;
- }
-
- function processRequest(method, url, data, headers) {
- if (method !== 'GET') {
- return [405, 'Unknown request'];
- } else if (!this.requestHasToken) {
- return [401, 'A valid token is required'];
- } else if (!this.userIsAuthenticated) {
- return [401, 'Invalid token'];
- }
-
- return [200, getPreferences()];
- }
-
- api.register('/preferences', 'get', processRequest);
-
-} );
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/modules/preferences/index.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/modules/preferences/index.js b/rave-portal-ng/mock-api/modules/preferences/index.js
new file mode 100644
index 0000000..58544ac
--- /dev/null
+++ b/rave-portal-ng/mock-api/modules/preferences/index.js
@@ -0,0 +1,14 @@
+/*
+ * preferences
+ * Sets up the preferences section of the API. This includes two things:
+ * the actual endpoints and methods for retrieving data
+ *
+ */
+
+define(function(require) {
+ var api = require('../../core.js');
+
+ // Register our endpoints
+ var endpoint = require('./endpoint');
+ api.registerEndpoint(endpoint);
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/modules/preferences/put.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/modules/preferences/put.js b/rave-portal-ng/mock-api/modules/preferences/put.js
deleted file mode 100644
index 845a894..0000000
--- a/rave-portal-ng/mock-api/modules/preferences/put.js
+++ /dev/null
@@ -1,56 +0,0 @@
-define(function(require) {
- 'use strict';
-
- var api = require('../../core.js');
- require('underscore/underscore');
-
- function updatePreferences(data) {
- var searchParams;
-
- // Loop through each data point, updating the corresponding preference
- // in the database.
- _.each(data, function(value, key) {
- searchParams = {
- key: key
- };
- api.db.update('preferences', searchParams, function(row) {
- row.value = value;
- return row;
- });
- });
- api.db.commit();
-
- // This is exactly what we do in the GET method. We might
- // want to DRY this up, but it's a mock API so no big deal.
- var results = api.db.query('preferences');
- var preferences = {};
-
- _.each(results, function(item) {
- preferences[item.key] = item.value;
- });
-
- return preferences;
- }
-
- function processRequest(method, url, data, headers) {
- if (method !== 'PUT') {
- return [405, 'Unknown request'];
- } else if (!this.requestHasToken) {
- return [401, 'A valid token is required'];
- } else if (!this.userIsAuthenticated) {
- return [401, 'Invalid token'];
- }
-
- data = angular.fromJson(data);
-
- var updatedPreferences = updatePreferences(data);
- if (!updatedPreferences) {
- return [500, 'An internal database error has occurred'];
- }
-
- return [200, updatedPreferences];
- }
-
- api.register('/preferences', 'put', processRequest);
-
-} );
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/modules/user/db.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/modules/user/db.js b/rave-portal-ng/mock-api/modules/user/db.js
new file mode 100644
index 0000000..3dd351f
--- /dev/null
+++ b/rave-portal-ng/mock-api/modules/user/db.js
@@ -0,0 +1,54 @@
+/*
+ * db
+ * Methods for getting and setting users.
+ *
+ */
+
+define(function(require) {
+ var api = require('../../core.js');
+
+ // The whitelisted keys that we send back with our request for the users
+ var userKeys = [
+ 'ID',
+ 'username',
+ 'description',
+ 'firstName',
+ 'lastName',
+ 'locked',
+ 'enabled',
+ 'expired',
+ 'authorities',
+ 'openIdUrl',
+ 'email'
+ ];
+
+ var userDb = {
+
+ // Retrieve the user by an identifier
+ get: function(identifier, filter) {
+
+ // Whether or not we want to filter the user's data.
+ // Filtering removes data we wouldn't want to send back,
+ // like passwords and tokens. Filtering is true by default
+ if (typeof filter === 'undefined') {
+ filter = true;
+ }
+
+ var results = api.db.query('users', identifier);
+
+ var user = results[0];
+
+ // If we don't have a user, then we return false
+ if (!user || results.length > 1) {
+ return false;
+ }
+
+ // If we want to filter, then do it
+ user = filter ? _.pick(user, userKeys) : user;
+
+ return user;
+ }
+ };
+
+ return userDb;
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/util/endpoint.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/util/endpoint.js b/rave-portal-ng/mock-api/util/endpoint.js
new file mode 100644
index 0000000..9792164
--- /dev/null
+++ b/rave-portal-ng/mock-api/util/endpoint.js
@@ -0,0 +1,88 @@
+/*
+ * endpoint
+ * Defines a RESTful endpoint
+ *
+ */
+
+define(function(require) {
+ var _ = require('underscore');
+ var paramsFromUrl = require('./params');
+ var ErrorResponse = require('./error-response');
+ var tokenUtil = require('./token-util');
+ var userDb = require('../modules/user/db');
+
+ // These are the valid options that you can pass into
+ // a new endpoint
+ var endpointOptions = [
+ 'url',
+ 'authorize',
+ 'get',
+ 'post',
+ 'delete',
+ 'put'
+ ];
+
+ var Endpoint = function(options) {
+
+ // Merge valid options directly into the endpoint
+ _.extend(this, _.pick(options, endpointOptions));
+ };
+
+ _.extend(Endpoint.prototype, {
+
+ // By default, all requests are
+ authorize: true,
+
+ // What is ultimately returned from the endpoint.
+ callback: function(method, url, data, headers) {
+
+ // Our current user, if there is one.
+ var currentUser;
+
+ // The first thing we need to check for every endpoint is if we want to authorize or not
+ if (this.authorize) {
+
+ // Attempt to get our token from the headers
+ var token = tokenUtil.tokenFromHeaders(headers);
+
+ // If it doesn't exist, then we throw an error
+ if (!token) {
+ return new ErrorResponse(401, 'A valid token is required.');
+ }
+
+ // Otherwise, we try to get the user from the token
+ var user = userDb.get({
+ sessionToken: token
+ });
+
+ // Again, throw an error if there's no user
+ if (!user) {
+ return new ErrorResponse(401, 'Invalid token.');
+ }
+
+ // Otherwise, we set our currentUser as the user.
+ currentUser = user;
+ }
+
+ // Get our query parameters from the url
+ var params = paramsFromUrl(url);
+
+ // Ensure that our method is lowercase
+ method = method.toLowerCase();
+
+ var callback = this[method];
+
+ // If we have the associated method, then we call it
+ if (_.isFunction(callback)) {
+ return callback(url, data, headers, params, currentUser);
+ }
+
+ // Otherwise, this is an unhandled request.
+ else {
+ return new ErrorResponse(405, 'Unknown request');
+ }
+ }
+ });
+
+ return Endpoint;
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/util/error-response.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/util/error-response.js b/rave-portal-ng/mock-api/util/error-response.js
new file mode 100644
index 0000000..be1407b
--- /dev/null
+++ b/rave-portal-ng/mock-api/util/error-response.js
@@ -0,0 +1,15 @@
+/*
+ * error
+ * A convenience class to generate a JSON error.
+ *
+ */
+
+define(function(require) {
+ var ErrorResponse = function(code, msg) {
+ return [code, {
+ message: msg
+ }];
+ };
+
+ return ErrorResponse;
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/util/params.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/util/params.js b/rave-portal-ng/mock-api/util/params.js
new file mode 100644
index 0000000..2c0cbd9
--- /dev/null
+++ b/rave-portal-ng/mock-api/util/params.js
@@ -0,0 +1,37 @@
+/*
+ * params
+ * A function to generate the query parameters from a URL
+ *
+ */
+
+define(function(require) {
+
+ // Pass in the URL; get back your parameters.
+ return function(str) {
+ str = str.split('?')[1];
+ if(typeof str !== 'string' || str.length === 0) {
+ return {};
+ }
+ var s = str.split('&');
+ var sLength = s.length;
+ var bit, query = {}, first, second;
+ for (var i = 0; i < sLength; i++) {
+ bit = s[i].split('=');
+ first = decodeURIComponent(bit[0]);
+ if(first.length === 0) {
+ continue;
+ }
+ second = decodeURIComponent(bit[1]);
+ if(typeof query[first] === 'undefined') {
+ query[first] = second;
+ }
+ else if(query[first] instanceof Array) {
+ query[first].push(second);
+ }
+ else {
+ query[first] = [query[first], second];
+ }
+ }
+ return query;
+ };
+});
http://git-wip-us.apache.org/repos/asf/rave/blob/fa312487/rave-portal-ng/mock-api/util/token-util.js
----------------------------------------------------------------------
diff --git a/rave-portal-ng/mock-api/util/token-util.js b/rave-portal-ng/mock-api/util/token-util.js
new file mode 100644
index 0000000..12dcdbb
--- /dev/null
+++ b/rave-portal-ng/mock-api/util/token-util.js
@@ -0,0 +1,30 @@
+/*
+ * tokenUtil
+ * Utility methods for working with tokens.
+ * Eventually we will also generate tokens in here.
+ *
+ *
+ */
+
+define(function(require) {
+
+ var tokenUtil = {
+
+ // Get the token from the headers. If it doesn't
+ // exist, or is invalid, then a value of false is returned
+ tokenFromHeaders: function(headers) {
+ if (!headers.Authorization) {
+ return false;
+ }
+
+ var token = headers.Authorization.replace('Basic ', '');
+ if (token.length !== 32) {
+ return false;
+ }
+
+ return token;
+ }
+ };
+
+ return tokenUtil;
+});