/
secure.js
110 lines (109 loc) · 3.46 KB
/
secure.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
(function() {
module.exports = {
"Function@": {
securedTestFunction: { // for testing purposes
execute: [] // no execution allowed
},
addRoles: { // only dbo can add roles to a user
execute: ["dbo"]
},
clear: { // only dbo can clear
execute: ["dbo"]
},
deleteUser: {
execute: ["dbo"]
},
entries: { // only dbo can list entries
execute: ["dbo"]
},
entry: {
execute: ["dbo"]
},
keys: { // only dbo can list keys
execute: ["dbo"]
},
removeRoles: {
execute: ["dbo"]
},
resetPassword: { // only user themself or dbo can start a password reset
execute({argumentsList,user}) {
return user.roles.dbo || argumentsList[0]===user.userName
}
},
sendMail: { // only dbo can send mail
execute: ["dbo"]
},
updateUser: { // only user themself or dbo can update user properties
execute({argumentsList,user}) {
return user.roles.dbo || argumentsList[0]===user.userName
}
},
values: { // only dbo can list values
execute: ["dbo"]
}
},
"User@": { // key to control, use <cname>@ for classes
// read: ["<role>",...], // array or map of roles to allow get, not specifying means all have get
// write: {<role>:true}, // array or map of roles to allow set, not specifying means all have set
// a filter function can also be used
// action with be "get" or "set", not returning anything will result in denial
// not specifying a filter function will allow all get and set, unless controlled above
// a function with the same call signature can also be used as a property value above
filter({action,user,data,request}) {
// very restrictive, don't return a user record unless requested by the dbo or data subject
if(user.roles.dbo || user.userName===data.userName) {
return data;
}
},
keys: { // only applies to objects
roles: {
// only dbo's and data subject can get roles
read({action,user,object,key,request}) { return user.roles.dbo || object.userName===user.userName; },
},
hash: {
// only dbo's can get password hashes
read: ["dbo"],
// only the dbo and data subject can set a hash
write({action,user,object,key,request}) { return user.roles.dbo || object.userName===user.userName; },
},
salt: {
// example of alternate control form, only dbo's can get password salts
read: {
dbo: true
},
// only the dbo and data subject can set a salt
write({action,user,object,key,request}) { return user.roles.dbo || object.userName===user.userName; },
},
name({action,user,data,request}) { return data; } // example, same as no access control
}
/* keys could also be a function
keys({action,user,data,key,request})
*/
},
securedTestReadKey: { // for testing purposes
read: [] // no gets allowed
},
securedTestWriteKey: { // for testing purposes
write: [] // no sets allowed
},
// Edges are just nested keys or wildcards, e.g.
securedTestEdge: {
keys: {
_: { // matches any sub-edge
public: {
read() { return true; },
write() { return true; }
},
private: {
read() { return false; },
write() { return false; }
}
}
}
},
[/\!.*/]: { // prevent direct index access by anyone other than a dbo, changing this may create a data inference leak
read: ["dbo"],
write: ["dbo"]
}
}
}).call(this);