forked from HabitRPG/habitica
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstore.coffee
117 lines (92 loc) · 3.71 KB
/
store.coffee
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
111
112
113
114
115
116
117
derbyAuth = require('derby-auth/store')
###
Setup read / write access
@param store
###
module.exports.customAccessControl = (store) ->
userAccess(store)
partySystem(store)
REST(store)
###
General user access
###
userAccess = (store) ->
store.readPathAccess "users.*", -> # captures, accept, err ->
accept = arguments[arguments.length-2]
err = arguments[arguments.length - 1]
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(false) if derbyAuth.bustedSession(@)
accept = arguments[arguments.length - 2]
uid = arguments[0]
accept (uid is @session.userId) or derbyAuth.isServer(@)
store.writeAccess "*", "users.*", -> # captures, value, accept, err ->
accept = arguments[arguments.length-2]
err = arguments[arguments.length - 1]
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(true) if derbyAuth.isServer(@)
return accept(false) if derbyAuth.bustedSession(@)
captures = arguments[0].split('.')
uid = captures.shift()
attrPath = captures.join('.') # new array shifted left, after shift() was run
# public access to users.*.party.invitation (TODO, lock down a bit more)
if (attrPath == 'party.invitation')
return accept(true)
# Same session (user.id = this.session.userId)
return accept(true) if uid is @session.userId
accept(false)
store.writeAccess "*", "users.*.balance", (id, newBalance, accept, err) ->
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(false) if derbyAuth.bustedSession(@)
oldBalance = @session.req?._racerModel?.get("users.#{id}.balance") || 0
purchasingSomethingOnClient = newBalance < oldBalance
accept(purchasingSomethingOnClient or derbyAuth.isServer(@))
store.writeAccess "*", "users.*.flags.ads", -> # captures, value, accept, err ->
accept = arguments[arguments.length - 2]
err = arguments[arguments.length - 1]
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(false) if derbyAuth.bustedSession(@)
accept(derbyAuth.isServer(@))
###
REST
Get user with API token
###
REST = (store) ->
store.query.expose "users", "withIdAndToken", (uid, token) ->
@where("id").equals(uid)
.where('apiToken').equals(token)
.findOne()
store.queryAccess "users", "withIdAndToken", (uid, token, accept, err) ->
return accept(true) if uid && token
accept(false) # only user has id & token
###
Party permissions
###
partySystem = (store) ->
store.query.expose "users", "party", (ids) ->
@where("id").within(ids)
.only('stats',
'items',
'party',
'preferences',
'auth.local.username',
'auth.facebook.displayName')
store.queryAccess "users", "party", (ids, accept, err) ->
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(false) if derbyAuth.bustedSession(@)
accept(true) # no harm in public user stats
store.query.expose "parties", "withId", (id) ->
@where("id").equals(id)
.findOne()
store.queryAccess "parties", "withId", (id, accept, err) ->
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(false) if derbyAuth.bustedSession(@)
accept(true)
store.readPathAccess "parties.*", ->
accept = arguments[arguments.length-2]
accept(true)
store.writeAccess "*", "parties.*", ->
accept = arguments[arguments.length-2]
err = arguments[arguments.length - 1]
# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@)
return accept(false) if derbyAuth.bustedSession(@)
accept(true)