1 /** 2 * @fileOverview This file provides classes related to authentication and role based permissions. 3 * @author <a href="mailto:paul.bottin+creds@gmail.com">Paul Bottin</a> 4 * @version 1.0.0 5 */ 6 7 /** 8 * provides two classes, {@link creds.users} and {@link creds.roles}<br/> 9 * @example 10 * var creds = require('creds'); 11 * 12 * var u = creds.users({ 13 * 14 * // passwords 15 * 'admin': 'nimda', 16 * 'user': 'resu' 17 * 18 * }); 19 * 20 * var r = creds.roles({ 21 * 22 * // users 23 * 'anonymous': [], 24 * 'admin': ['admins'], 25 * 'user': ['users'], 26 * 27 * // groups 28 * 'admins': ['users'], 29 * 'users': ['registered'], 30 * 'registered': [] 31 * 32 * }); 33 * 34 * u('admin', 'nimda'); // => true 35 * r('admin', 'registered'); // => true 36 * 37 * @name creds 38 * @namespace 39 */ 40 41 /** 42 * stores user names and their passwords 43 * @name creds.users 44 * @constructor 45 * @param {Object} data 46 * @returns {creds.users} 47 */ 48 function users (data) { 49 50 /** 51 * checks if the given password matches that of the given user 52 * @name creds.users#checkUser 53 * @function 54 * @param {String} username 55 * @param {String} password 56 * @returns {Boolean} 57 */ 58 function checkUser (username, password) { 59 return (username !== undefined) // no user name given 60 && (username.length > 0) // empty user name given 61 && (data[username] !== undefined) // unknown user name 62 && (password !== undefined) // no password given 63 && (password.length > 0) // empty password given 64 && (data[username] == password) // password mismatch 65 ; 66 }; 67 checkUser.checkUser = checkUser; 68 69 /** 70 * gets a list of known user names 71 * @name creds.users#usernames 72 * @property 73 * @constant 74 * @type Array 75 */ 76 checkUser.__defineGetter__('usernames', function () { 77 return Object.keys(data); 78 }); 79 80 Object.freeze(checkUser); 81 Object.seal(checkUser); 82 return checkUser; 83 } 84 exports.users = users; 85 Object.freeze(users); 86 Object.seal(users); 87 88 /** 89 * stores role assignments 90 * @name creds.roles 91 * @constructor 92 * @param {Object} data 93 * @returns {creds.roles} 94 */ 95 function roles (data) { 96 97 /** 98 * checks if the role is membership or owns inherited membership 99 * @name creds.roles#checkRole 100 * @function 101 * @param {String} role 102 * @param {String} membership 103 * @returns {Boolean} 104 */ 105 function checkRole (role, membership) { 106 var result = false; 107 if ( (role !== undefined) // no role given 108 && (role.length > 0) // empty role given 109 && (data[role] !== undefined) // unknown role 110 && (membership !== undefined) // no membership given 111 && (membership.length > 0) // empty membership given 112 ) { 113 if (role == membership) 114 result = true; 115 data[role].forEach(function (m) { 116 if (membership == m) 117 result = true; 118 else 119 result = result || checkRole(m, membership); 120 }); 121 122 } 123 return result; 124 } 125 checkRole.checkRole = checkRole; 126 127 /** 128 * gets a list of known roles 129 * @name creds.roles#roles 130 * @property 131 * @constant 132 * @type Array 133 */ 134 checkRole.__defineGetter__('roles', function () { 135 return Object.keys(data); 136 }); 137 138 /** 139 * gets all inherited roles of a role 140 * @name creds.roles#activeRoles 141 * @function 142 * @param {String} role 143 * @returns {Array} 144 */ 145 function activeRoles (role) { 146 return Object.keys(data).filter(function (r) { 147 return checkRole(role, r); 148 });; 149 } 150 checkRole.activeRoles = activeRoles; 151 152 Object.freeze(checkRole); 153 Object.seal(checkRole); 154 return checkRole; 155 } 156 exports.roles = roles; 157 158 Object.freeze(roles); 159 Object.seal(roles); 160 161 Object.freeze(exports); 162 Object.seal(exports); 163