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;
+});