Last active
October 27, 2015 04:29
-
-
Save lbrenman/69b3fcec38ce3224f8bd to your computer and use it in GitHub Desktop.
Arrow Custom Authentication Scheme - API Management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Arrow = require("arrow"); | |
var Model = Arrow.Model.reduce("appc.salesforce/Account","Account",{ | |
"fields": { | |
"Name": { | |
"type": "string", | |
"description": "Account Name", | |
"readonly": false, | |
"maxlength": 255, | |
"required": true, | |
"optional": false, | |
"writeonly": false | |
}, | |
"Type": { | |
"type": "string", | |
"description": "Account Type", | |
"readonly": false, | |
"maxlength": 40, | |
"required": false, | |
"optional": true, | |
"writeonly": false | |
}, | |
"Website": { | |
"type": "string", | |
"description": "Website", | |
"readonly": false, | |
"maxlength": 255, | |
"required": false, | |
"optional": true, | |
"writeonly": false | |
} | |
}, | |
"actions": [ | |
"create", | |
"read", | |
"update", | |
"delete", | |
"deleteAll" | |
], | |
"singular": "Account", | |
"plural": "Accounts" | |
}); | |
module.exports = Model; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Arrow = require("arrow"); | |
var keygen = require("keygenerator"); | |
var Model = Arrow.createModel("apiuser",{ | |
"fields": { | |
"username": { | |
"type": "String" | |
}, | |
"key": { | |
"type": "String", | |
"set":function(val,key,model){ | |
return keygen._(); | |
} | |
}, | |
"enabled": { | |
"type": "Boolean", | |
"default": true, | |
}, | |
"count": { | |
"type": "Number", | |
"default": 0, | |
} | |
}, | |
"before": "validateapiuser", | |
"connector": "appc.arrowdb", | |
"actions": [ | |
"create", | |
"read", | |
"update", | |
"delete", | |
"deleteAll" | |
], | |
"singular": "apiuser", | |
"plural": "apiusers" | |
}); | |
module.exports = Model; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Arrow = require("arrow"); | |
var Model = Arrow.createModel("database",{ | |
"fields": { | |
"fname": { | |
"type": "String" | |
}, | |
"lname": { | |
"type": "String" | |
}, | |
"title": { | |
"type": "String" | |
} | |
}, | |
"connector": "appc.arrowdb", | |
"actions": [ | |
"create", | |
"read", | |
"update", | |
"delete", | |
"deleteAll" | |
], | |
// "before": "checkheaders", | |
"singular": "database", | |
"plural": "databases" | |
}); | |
module.exports = Model; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* this is your configuration file defaults. | |
* | |
* You can create additional configuration files to that the server will load based on your | |
* environment. For example, if you want to have specific settings for production which are different | |
* than your local development environment, you can create a production.js and a local.js. Any changes | |
* in those files will overwrite changes to this file (a object merge is performed). By default, your | |
* local.js file will not be commited to git or the registry. | |
* | |
* This is a JavaScript file (instead of JSON) so you can also perform logic in this file if needed. | |
*/ | |
module.exports = { | |
// these are your generated API keys. They were generated uniquely when you created this project. | |
// DO NOT SHARE these keys with other projects and be careful with these keys since they control | |
// access to your API using the default configuration. if you don't want two different keys for | |
// production and test (not recommended), use the key 'apikey'. To simulate running in production, | |
// set the environment variable NODE_ENV to production before running such as: | |
// | |
// NODE_ENV=production appc run | |
// | |
// production key, this is the key that will be required when you are running in production | |
apikey_production: 'OEp0jzsqpke8NUCT0uoKSk8HQRn27DbP', | |
// development key, this is the key that will be required when you are testing non-production (such as locally) | |
apikey_development: '8u6FTQCBWoCifXRXm9PTMkxznosVqvZd', | |
// by default the authentication strategy is 'basic' which will use HTTP Basic Authorization where the | |
// usename is the key and the password is blank. the other option is 'apikey' where the value of the | |
// APIKey header is the value of the key. you can also set this to 'plugin' and define the key 'APIKeyAuthPlugin' | |
// which points to a file or a module that implements the authentication strategy | |
// APIKeyAuthType: 'basic', | |
APIKeyAuthType: 'plugin', | |
APIKeyAuthPlugin: './lib/plugin.js', | |
adminsecret: 'adminsecret', | |
// logging configuration | |
logging: { | |
// location of the logs if enabled | |
logdir: './logs', | |
// turn on transaction logs | |
transactionLogEnabled: true | |
}, | |
// prefix to use for apis | |
apiPrefix: '/api', | |
// control the settings for the admin website | |
admin: { | |
// control whether the admin website is available | |
enabled: true, | |
// the prefix to the admin website | |
prefix: '/arrow', | |
// the prefix for the public apidocs website | |
apiDocPrefix: '/apidoc', | |
// if you set disableAuth, in production only your API docs will show up | |
disableAuth: false, | |
// if you set disableAPIDoc, you APIs docs will not show up (regardless of disableAuth) | |
disableAPIDoc: false, | |
// set to true to allow the admin website to be accessed in production. however, you will still need a | |
// login unless disableAuth is false. if you set this to false, the admin website will not be enabled | |
// when in production (still respects enabled above) | |
enableAdminInProduction: true, | |
// set the email addresses you want to enable while in production (assuming enableAdminInProduction=true) | |
validEmails: ["[email protected]"], | |
// set the organization ids you want to enable while in production (assuming enableAdminInProduction=true) | |
validOrgs: [100000142] | |
}, | |
// you can generally leave this as-is since it is generated for each new project you created. | |
session: { | |
encryptionAlgorithm: 'aes256', | |
encryptionKey: '8sYsej4sLe9hFmeo24rfwOTgXkdOjp5wbzT60ivof1k=', | |
signatureAlgorithm: 'sha512-drop256', | |
signatureKey: 'NXbG67rJOv6v2LmA8BmCmWICNPrkrT/mk8K+zO6TgCdeKmB1Cm2o4C7HTF5lbyPPwN1c1tTdS2vek4/6m81QXA==', | |
secret: 'D9BBBhcJ62UvRt4c+ijAwFwlcx6Ykilj', // should be a large unguessable string | |
duration: 86400000, // how long the session will stay valid in ms | |
activeDuration: 300000 // if expiresIn < activeDuration, the session will be extended by activeDuration milliseconds | |
}, | |
// your connector configuration goes here | |
connectors: { | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Arrow = require('arrow'); | |
function Plugin(server) { | |
console.log("Plugin()"); | |
this.config = server.config; | |
} | |
Plugin.prototype.matchURL = function(request) { | |
console.log("matchURL(), request.url = "+request.url); | |
// Validate all apis | |
return true; | |
}; | |
Plugin.prototype.validateRequest = function(request, response, callback) { | |
console.log("validateRequest(), request.url = "+request.url); | |
//admins have access to all APIs | |
if (request.headers['admin-secret'] && request.headers['admin-secret'] === this.config.adminsecret) { | |
callback(null, true); | |
return false; | |
} | |
if(request.url.indexOf('/api/apiuser') !== 0) { //don't allow access to the apiuser database | |
var model = Arrow.getModel("apiuser"); | |
model.query({key: request.headers['x-api-key'] || "key not found"}, function(err, collection){ | |
if(err) { | |
callback(null, false); | |
} else { | |
if(collection.length>0){ | |
model.findOne(collection[0].id, function(err, data){ | |
if(err) { | |
callback(errorMsg_serverError, false); | |
} else { | |
if(data.enabled) { | |
data.count++; | |
data.update(); | |
callback(null, true); | |
} else { | |
callback(null, false); | |
} | |
} | |
}); | |
} else { | |
callback(null, false); | |
} | |
} | |
}); | |
} else { | |
callback(null, false); | |
} | |
}; | |
// Add the admin-secret header for internal requests | |
Plugin.prototype.applyCredentialsForTest = function(options) { | |
options.headers['admin-secret'] = this.config.adminsecret; | |
}; | |
// Do not process the response | |
Plugin.prototype.applyResponseForTest = function(response, body) { | |
return body; | |
}; | |
module.exports = Plugin; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Arrow = require('arrow'); | |
var PreBlock = Arrow.Block.extend({ | |
name: 'validateapiuser', | |
description: 'validate api user', | |
action: function (req, resp, next) { | |
if((req.method==="POST" || req.method==="PUT")) { | |
// console.log("req.params = "+JSON.stringify(req.params)); | |
var model = Arrow.getModel("apiuser"); | |
model.query({username: req.params.username}, function(err, data){ | |
if(err) { | |
// console.log('error getting apisuer database, err = '+err); | |
resp.response.status(500); //workaround - https://jira.appcelerator.org/browse/API-852 | |
resp.send({"error": "cannot access user api database"}); | |
next(false); | |
} else { | |
// console.log("data retreived from apiuser length = "+data.length); | |
if(data.length > 0) { | |
resp.response.status(500); //workaround - https://jira.appcelerator.org/browse/API-852 | |
resp.send({"error": "duplicate username"}); | |
next(false); | |
} else { | |
next(); | |
} | |
} | |
}); | |
} else { | |
next(); | |
} | |
} | |
}); | |
module.exports = PreBlock; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment