Add reference documentation using sdocs
This commit is contained in:
parent
a47317de0d
commit
fcc4bba82d
|
@ -3,6 +3,14 @@
|
|||
"content": [
|
||||
"docs/api.md",
|
||||
"docs/api-app.md",
|
||||
"lib/models/access-token.js",
|
||||
"lib/models/access-context.js",
|
||||
"lib/models/acl.js",
|
||||
"lib/models/application.js",
|
||||
"lib/models/email.js",
|
||||
"lib/models/model.js",
|
||||
"lib/models/role.js",
|
||||
"lib/models/user.js",
|
||||
"docs/api-datasource.md",
|
||||
"docs/api-geopoint.md",
|
||||
"docs/api-model.md",
|
||||
|
|
|
@ -6,7 +6,7 @@ var debug = require('debug')('loopback:security:access-context');
|
|||
* Access context represents the context for a request to access protected
|
||||
* resources
|
||||
*
|
||||
* The AccessContext instance contains the following properties:
|
||||
* @class
|
||||
* @property {Principal[]} principals An array of principals
|
||||
* @property {Function} model The model class
|
||||
* @property {String} modelName The model name
|
||||
|
@ -175,7 +175,7 @@ AccessContext.prototype.debug = function() {
|
|||
* @param {*} id The princiapl id
|
||||
* @param {String} [name] The principal name
|
||||
* @returns {Principal}
|
||||
* @constructor
|
||||
* @class
|
||||
*/
|
||||
function Principal(type, id, name) {
|
||||
if (!(this instanceof Principal)) {
|
||||
|
@ -211,7 +211,7 @@ Principal.prototype.equals = function (p) {
|
|||
* @param {String} accessType The access type
|
||||
* @param {String} permission The permission
|
||||
* @returns {AccessRequest}
|
||||
* @constructor
|
||||
* @class
|
||||
*/
|
||||
function AccessRequest(model, property, accessType, permission) {
|
||||
if (!(this instanceof AccessRequest)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
* Module Dependencies.
|
||||
*/
|
||||
|
||||
|
@ -14,6 +14,10 @@ var Model = require('../loopback').Model
|
|||
|
||||
/**
|
||||
* Default AccessToken properties.
|
||||
*
|
||||
* @property id {String} - Generated token ID
|
||||
* @property ttl {Number} - Time to live
|
||||
* @property created {Date} - When the token was created
|
||||
*/
|
||||
|
||||
var properties = {
|
||||
|
@ -25,7 +29,15 @@ var properties = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Extends from the built in `loopback.Model` type.
|
||||
* Token based authentication and access control.
|
||||
*
|
||||
* **Default ACLs**
|
||||
*
|
||||
* - DENY EVERYONE `*`
|
||||
* - ALLOW EVERYONE create
|
||||
*
|
||||
* @class
|
||||
* @inherits {Model}
|
||||
*/
|
||||
|
||||
var AccessToken = module.exports = Model.extend('AccessToken', properties, {
|
||||
|
@ -44,12 +56,22 @@ var AccessToken = module.exports = Model.extend('AccessToken', properties, {
|
|||
]
|
||||
});
|
||||
|
||||
/**
|
||||
* Anonymous Token
|
||||
*
|
||||
* ```js
|
||||
* assert(AccessToken.ANONYMOUS.id === '$anonymous');
|
||||
* ```
|
||||
*/
|
||||
|
||||
AccessToken.ANONYMOUS = new AccessToken({id: '$anonymous'});
|
||||
|
||||
/**
|
||||
* Create a cryptographically random access token id.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {String} token
|
||||
*/
|
||||
|
||||
AccessToken.createAccessTokenId = function (fn) {
|
||||
|
@ -85,7 +107,9 @@ AccessToken.beforeCreate = function (next, data) {
|
|||
*
|
||||
* @param {ServerRequest} req
|
||||
* @param {Object} [options] Options for finding the token
|
||||
* @param {Function} callback Calls back with a token if one exists otherwise null or an error.
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {AccessToken} token
|
||||
*/
|
||||
|
||||
AccessToken.findForRequest = function(req, options, cb) {
|
||||
|
@ -116,6 +140,14 @@ AccessToken.findForRequest = function(req, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the token.
|
||||
*
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {Boolean} isValid
|
||||
*/
|
||||
|
||||
AccessToken.prototype.validate = function(cb) {
|
||||
try {
|
||||
assert(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
Schema ACL options
|
||||
|
||||
Object level permissions, for example, an album owned by a user
|
||||
|
@ -44,7 +44,7 @@ var AccessRequest = ctx.AccessRequest;
|
|||
var role = require('./role');
|
||||
var Role = role.Role;
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Schema for Scope which represents the permissions that are granted to client
|
||||
* applications by the resource owner
|
||||
*/
|
||||
|
@ -53,7 +53,6 @@ var ScopeSchema = {
|
|||
description: String
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resource owner grants/delegates permissions to client applications
|
||||
*
|
||||
|
@ -61,10 +60,31 @@ var ScopeSchema = {
|
|||
* from the resource owner (user or system)?
|
||||
*
|
||||
* Scope has many resource access entries
|
||||
* @type {createModel|*}
|
||||
* @class
|
||||
*/
|
||||
var Scope = loopback.createModel('Scope', ScopeSchema);
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given scope is allowed to access the model/property
|
||||
* @param {String} scope The scope name
|
||||
* @param {String} model The model name
|
||||
* @param {String} property The property/method/relation name
|
||||
* @param {String} accessType The access type
|
||||
* @callback {Function} callback
|
||||
* @param {String|Error} err The error object
|
||||
* @param {AccessRequest} result The access permission
|
||||
*/
|
||||
Scope.checkPermission = function (scope, model, property, accessType, callback) {
|
||||
Scope.findOne({where: {name: scope}}, function (err, scope) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
} else {
|
||||
ACL.checkPermission(ACL.SCOPE, scope.id, model, property, accessType, callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* System grants permissions to principals (users/applications, can be grouped
|
||||
* into roles).
|
||||
|
@ -75,7 +95,6 @@ var Scope = loopback.createModel('Scope', ScopeSchema);
|
|||
* For a given principal, such as client application and/or user, is it allowed
|
||||
* to access (read/write/execute)
|
||||
* the protected resource?
|
||||
*
|
||||
*/
|
||||
var ACLSchema = {
|
||||
model: String, // The name of the model
|
||||
|
@ -105,6 +124,14 @@ var ACLSchema = {
|
|||
principalId: String
|
||||
};
|
||||
|
||||
/**
|
||||
* A Model for access control meta data.
|
||||
*
|
||||
* @header ACL
|
||||
* @class
|
||||
* @inherits Model
|
||||
*/
|
||||
|
||||
var ACL = loopback.createModel('ACL', ACLSchema);
|
||||
|
||||
ACL.ALL = AccessContext.ALL;
|
||||
|
@ -160,7 +187,7 @@ ACL.getMatchingScore = function getMatchingScore(rule, req) {
|
|||
* Resolve permission from the ACLs
|
||||
* @param {Object[]) acls The list of ACLs
|
||||
* @param {Object} req The request
|
||||
* @returns {Object} The effective ACL
|
||||
* @returns {AccessRequest} result The effective ACL
|
||||
*/
|
||||
ACL.resolvePermission = function resolvePermission(acls, req) {
|
||||
// Sort by the matching score in descending order
|
||||
|
@ -255,7 +282,7 @@ ACL.getStaticACLs = function getStaticACLs(model, property) {
|
|||
*
|
||||
* @callback callback
|
||||
* @param {String|Error} err The error object
|
||||
* @param {Object} the access permission
|
||||
* @param {AccessRequest} result The access permission
|
||||
*/
|
||||
ACL.checkPermission = function checkPermission(principalType, principalId,
|
||||
model, property, accessType,
|
||||
|
@ -309,28 +336,6 @@ ACL.prototype.debug = function() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given scope is allowed to access the model/property
|
||||
* @param {String} scope The scope name
|
||||
* @param {String} model The model name
|
||||
* @param {String} property The property/method/relation name
|
||||
* @param {String} accessType The access type
|
||||
* @param {Function} callback The callback function
|
||||
*
|
||||
* @callback callback
|
||||
* @param {String|Error} err The error object
|
||||
* @param {Object} the access permission
|
||||
*/
|
||||
Scope.checkPermission = function (scope, model, property, accessType, callback) {
|
||||
Scope.findOne({where: {name: scope}}, function (err, scope) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
} else {
|
||||
ACL.checkPermission(ACL.SCOPE, scope.id, model, property, accessType, callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the request has the permission to access
|
||||
* @param {Object} context
|
||||
|
@ -412,9 +417,8 @@ ACL.checkAccess = function (context, callback) {
|
|||
* @param {String} model The model name
|
||||
* @param {*} modelId The model id
|
||||
* @param {String} method The method name
|
||||
* @param callback The callback function
|
||||
*
|
||||
* @callback callback
|
||||
* @end
|
||||
* @callback {Function} callback
|
||||
* @param {String|Error} err The error object
|
||||
* @param {Boolean} allowed is the request allowed
|
||||
*/
|
||||
|
|
|
@ -106,6 +106,12 @@ function generateKey(hmacKey, algorithm, encoding) {
|
|||
return hmac.digest('base64');
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage client applications and organize their users.
|
||||
* @class
|
||||
* @inherits {Model}
|
||||
*/
|
||||
|
||||
var Application = loopback.createModel('Application', ApplicationSchema);
|
||||
|
||||
/*!
|
||||
|
@ -150,7 +156,8 @@ Application.register = function (owner, name, options, cb) {
|
|||
|
||||
/**
|
||||
* Reset keys for the application instance
|
||||
* @param cb
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
*/
|
||||
Application.prototype.resetKeys = function (cb) {
|
||||
this.clientKey = generateKey('client');
|
||||
|
@ -164,8 +171,9 @@ Application.prototype.resetKeys = function (cb) {
|
|||
|
||||
/**
|
||||
* Reset keys for a given application by the appId
|
||||
* @param appId
|
||||
* @param cb
|
||||
* @param {Any} appId
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
*/
|
||||
Application.resetKeys = function (appId, cb) {
|
||||
Application.findById(appId, function (err, app) {
|
||||
|
@ -178,10 +186,21 @@ Application.resetKeys = function (appId, cb) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Authenticate the application id and key.
|
||||
*
|
||||
* `matched` will be one of
|
||||
*
|
||||
* - clientKey
|
||||
* - javaScriptKey
|
||||
* - restApiKey
|
||||
* - windowsKey
|
||||
* - masterKey
|
||||
*
|
||||
* @param appId
|
||||
* @param key
|
||||
* @param cb
|
||||
* @param {Any} appId
|
||||
* @param {String} key
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {String} matched - The matching key
|
||||
*/
|
||||
Application.authenticate = function (appId, key, cb) {
|
||||
Application.findById(appId, function (err, app) {
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
/**
|
||||
/*!
|
||||
* Module Dependencies.
|
||||
*/
|
||||
|
||||
var Model = require('../loopback').Model
|
||||
, loopback = require('../loopback');
|
||||
|
||||
/**
|
||||
* Default Email properties.
|
||||
*/
|
||||
|
||||
var properties = {
|
||||
to: {type: String, required: true},
|
||||
from: {type: String, required: true},
|
||||
|
@ -18,7 +14,43 @@ var properties = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Extends from the built in `loopback.Model` type.
|
||||
* The Email Model.
|
||||
*
|
||||
* **Properties**
|
||||
*
|
||||
* - `to` - **{ String }** **required**
|
||||
* - `from` - **{ String }** **required**
|
||||
* - `subject` - **{ String }** **required**
|
||||
* - `text` - **{ String }**
|
||||
* - `html` - **{ String }**
|
||||
*
|
||||
* @class
|
||||
* @inherits {Model}
|
||||
*/
|
||||
|
||||
var Email = module.exports = Model.extend('Email', properties);
|
||||
|
||||
/**
|
||||
* Send an email with the given `options`.
|
||||
*
|
||||
* Example Options:
|
||||
*
|
||||
* ```json
|
||||
* {
|
||||
* from: "Fred Foo ✔ <foo@blurdybloop.com>", // sender address
|
||||
* to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers
|
||||
* subject: "Hello ✔", // Subject line
|
||||
* text: "Hello world ✔", // plaintext body
|
||||
* html: "<b>Hello world ✔</b>" // html body
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* See https://github.com/andris9/Nodemailer for other supported options.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Function} callback Called after the e-mail is sent or the sending failed
|
||||
*/
|
||||
|
||||
Email.prototype.send = function() {
|
||||
throw new Error('You must connect the Email Model to a Mail connector');
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
* Module Dependencies.
|
||||
*/
|
||||
var loopback = require('../loopback');
|
||||
|
@ -7,7 +7,10 @@ var modeler = new ModelBuilder();
|
|||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
* Define the built in loopback.Model.
|
||||
* The built in loopback.Model.
|
||||
*
|
||||
* @class
|
||||
* @param {Object} data
|
||||
*/
|
||||
|
||||
var Model = module.exports = modeler.define('Model');
|
||||
|
@ -124,7 +127,7 @@ function getACL() {
|
|||
* @param {String} method The method name
|
||||
* @param callback The callback function
|
||||
*
|
||||
* @callback callback
|
||||
* @callback {Function} callback
|
||||
* @param {String|Error} err The error object
|
||||
* @param {Boolean} allowed is the request allowed
|
||||
*/
|
||||
|
@ -136,7 +139,7 @@ Model.checkAccess = function(token, modelId, method, callback) {
|
|||
ACL.checkAccessForToken(token, this.modelName, modelId, methodName, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Determine the access type for the given `RemoteMethod`.
|
||||
*
|
||||
* @api private
|
||||
|
|
|
@ -26,6 +26,10 @@ var RoleMappingSchema = {
|
|||
principalId: String // The principal id
|
||||
};
|
||||
|
||||
/**
|
||||
* Map Roles to
|
||||
*/
|
||||
|
||||
var RoleMapping = loopback.createModel('RoleMapping', RoleMappingSchema, {
|
||||
relations: {
|
||||
role: {
|
||||
|
@ -43,7 +47,9 @@ RoleMapping.ROLE = 'ROLE';
|
|||
|
||||
/**
|
||||
* Get the application principal
|
||||
* @param callback
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {Application} application
|
||||
*/
|
||||
RoleMapping.prototype.application = function (callback) {
|
||||
if (this.principalType === RoleMapping.APPLICATION) {
|
||||
|
@ -57,7 +63,9 @@ RoleMapping.prototype.application = function (callback) {
|
|||
|
||||
/**
|
||||
* Get the user principal
|
||||
* @param callback
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {User} user
|
||||
*/
|
||||
RoleMapping.prototype.user = function (callback) {
|
||||
if (this.principalType === RoleMapping.USER) {
|
||||
|
@ -71,7 +79,9 @@ RoleMapping.prototype.user = function (callback) {
|
|||
|
||||
/**
|
||||
* Get the child role principal
|
||||
* @param callback
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {User} childUser
|
||||
*/
|
||||
RoleMapping.prototype.childRole = function (callback) {
|
||||
if (this.principalType === RoleMapping.ROLE) {
|
||||
|
@ -84,7 +94,8 @@ RoleMapping.prototype.childRole = function (callback) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Define the Role model with `hasMany` relation to RoleMapping
|
||||
* The Role Model
|
||||
* @class
|
||||
*/
|
||||
var Role = loopback.createModel('Role', RoleSchema, {
|
||||
relations: {
|
||||
|
@ -249,7 +260,9 @@ Role.registerResolver(Role.AUTHENTICATED, function(role, context, callback) {
|
|||
/**
|
||||
* Check if the user id is authenticated
|
||||
* @param {Object} context The security context
|
||||
* @param {Function} callback The callback function
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {Boolean} isAuthenticated
|
||||
*/
|
||||
Role.isAuthenticated = function isAuthenticated(context, callback) {
|
||||
process.nextTick(function() {
|
||||
|
@ -274,7 +287,9 @@ Role.registerResolver(Role.EVERYONE, function (role, context, callback) {
|
|||
*
|
||||
* @param {String} role The role name
|
||||
* @param {Object} context The context object
|
||||
* @param {Function} callback
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {Boolean} isInRole
|
||||
*/
|
||||
Role.isInRole = function (role, context, callback) {
|
||||
debug('isInRole(): %s %j', role, context);
|
||||
|
@ -355,7 +370,7 @@ Role.isInRole = function (role, context, callback) {
|
|||
* @param {Object} context The security context
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @callback callback
|
||||
* @callback {Function} callback
|
||||
* @param err
|
||||
* @param {String[]} An array of role ids
|
||||
*/
|
||||
|
|
|
@ -44,11 +44,7 @@ var properties = {
|
|||
status: String,
|
||||
created: Date,
|
||||
lastUpdated: Date
|
||||
}
|
||||
|
||||
/**
|
||||
* Default User options.
|
||||
*/
|
||||
};
|
||||
|
||||
var options = {
|
||||
acls: [
|
||||
|
@ -98,6 +94,19 @@ var options = {
|
|||
|
||||
/**
|
||||
* Extends from the built in `loopback.Model` type.
|
||||
*
|
||||
* Default `User` ACLs.
|
||||
*
|
||||
* - DENY EVERYONE `*`
|
||||
* - ALLOW EVERYONE `create`
|
||||
* - ALLOW OWNER `removeById`
|
||||
* - ALLOW EVERYONE `login`
|
||||
* - ALLOW EVERYONE `logout`
|
||||
* - ALLOW EVERYONE `findById`
|
||||
* - ALLOW OWNER `updateAttributes`
|
||||
*
|
||||
* @class
|
||||
* @inherits {Model}
|
||||
*/
|
||||
|
||||
var User = module.exports = Model.extend('User', properties, options);
|
||||
|
@ -105,11 +114,16 @@ var User = module.exports = Model.extend('User', properties, options);
|
|||
/**
|
||||
* Login a user by with the given `credentials`.
|
||||
*
|
||||
* ```js
|
||||
* User.login({username: 'foo', password: 'bar'}, function (err, token) {
|
||||
* console.log(token.id);
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param {Object} credentials
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
* @param {AccessToken} token
|
||||
*/
|
||||
|
||||
User.login = function (credentials, fn) {
|
||||
|
@ -150,11 +164,15 @@ User.login = function (credentials, fn) {
|
|||
/**
|
||||
* Logout a user with the given accessToken id.
|
||||
*
|
||||
* ```js
|
||||
* User.logout('asd0a9f8dsj9s0s3223mk', function (err) {
|
||||
* console.log(err || 'Logged out');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param {String} accessTokenID
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
*/
|
||||
|
||||
User.logout = function (tokenId, fn) {
|
||||
|
@ -188,8 +206,9 @@ User.prototype.hasPassword = function (plain, fn) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Verify a user's identity.
|
||||
* Verify a user's identity by sending them a confirmation email.
|
||||
*
|
||||
* ```js
|
||||
* var options = {
|
||||
* type: 'email',
|
||||
* to: user.email,
|
||||
|
@ -198,6 +217,7 @@ User.prototype.hasPassword = function (plain, fn) {
|
|||
* };
|
||||
*
|
||||
* user.verify(options, next);
|
||||
* ```
|
||||
*
|
||||
* @param {Object} options
|
||||
*/
|
||||
|
@ -266,6 +286,16 @@ User.prototype.verify = function (options, fn) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Confirm the user's identity.
|
||||
*
|
||||
* @param {Any} userId
|
||||
* @param {String} token The validation token
|
||||
* @param {String} redirect URL to redirect the user to once confirmed
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
*/
|
||||
User.confirm = function (uid, token, redirect, fn) {
|
||||
this.findById(uid, function (err, user) {
|
||||
if(err) {
|
||||
|
@ -288,6 +318,16 @@ User.confirm = function (uid, token, redirect, fn) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a short lived acess token for temporary login. Allows users
|
||||
* to change passwords if forgotten.
|
||||
*
|
||||
* @options {Object} options
|
||||
* @prop {String} email The user's email address
|
||||
* @callback {Function} callback
|
||||
* @param {Error} err
|
||||
*/
|
||||
|
||||
User.resetPassword = function(options, cb) {
|
||||
var UserModel = this;
|
||||
var ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL;
|
||||
|
@ -323,7 +363,7 @@ User.resetPassword = function(options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Setup an extended user model.
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue