UNPKG

6.44 kBJavaScriptView Raw
1var tape = require('tape')
2var pull = require('pull-stream')
3var pushable = require('pull-pushable')
4var mux = require('../')
5var cont = require('cont')
6var Permissions = require('../permissions')
7
8var api = {
9 login : 'async',
10 logout : 'async',
11 get : 'async',
12 put : 'async',
13 del : 'async',
14 read : 'source',
15 nested: {
16 get : 'async',
17 put : 'async',
18 del : 'async',
19 read : 'source'
20 }
21}
22
23function id (e) {
24 return e
25}
26
27var store = {
28 foo: 1,
29 bar: 2,
30 baz: 3
31}
32
33function createServerAPI (store) {
34 var rpc
35 var name = 'nobody'
36
37 //this wraps a session.
38
39 var perms = Permissions({allow: ['login']})
40
41 var session = {
42 //implement your own auth function.
43 //it should just set the allow and deny lists.
44
45 login: function (opts, cb) {
46 //allow read operations
47 if(opts.name === 'user' && opts.pass === "password")
48 perms({deny: ['put', 'del'], allow: null})
49
50 //allow write operations
51 else if(opts.name === 'admin' && opts.pass === "admin") //whatelse?
52 perms({deny: null, allow: null}) //allow everything
53
54 //
55 else if(opts.name === 'nested' && opts.pass === 'foofoo')
56 perms({
57 //read only access to nested methods
58 allow: ['nested'],
59 deny: [['nested', 'put'], ['nested', 'del']]
60 })
61
62 //you are nobody!
63 else
64 return cb(new Error('not authorized'))
65
66 name = opts.name
67
68 cb(null, {okay: true, name: name})
69 },
70 logout: function (cb) {
71 name = 'nobody'
72 perms({allow: ['login'], deny: null})
73 cb(null, {okay: true, user: name})
74 },
75 whoami: function (cb) {
76 cb(null, {okay: true, user: name})
77 },
78 get: function (key, cb) {
79 return cb(null, store[key])
80 },
81 put: function (key, value, cb) {
82 store[key] = value
83 cb()
84 },
85 del: function (key, cb) {
86 delete store[key]
87 cb()
88 },
89 read: function () {
90 return pull.values(
91 Object.keys(store).map(function (k) {
92 return {key: k, value: store[k]}
93 })
94 )
95 }
96 }
97
98 session.nested = session
99
100 return rpc = mux(null, api, id)(session, perms)
101}
102
103function createClientAPI() {
104 return mux(api, null, id)()
105}
106
107tape('secure rpc', function (t) {
108
109 var server = createServerAPI(store)
110 var client = createClientAPI()
111
112 var ss = server.createStream()
113 var cs = client.createStream()
114
115 pull(cs, ss, cs)
116
117 cont.para([
118 function (cb) {
119 client.get('foo', function (err) {
120 t.ok(err); cb()
121 })
122 },
123 function (cb) {
124 client.put('foo', function (err) {
125 t.ok(err); cb()
126 })
127 },
128 function (cb) {
129 client.del('foo', function (err) {
130 t.ok(err); cb()
131 })
132 },
133 function (cb) {
134 pull(client.read(), pull.collect(function (err) {
135 t.ok(err); cb()
136 }))
137 }
138 ])(function (err) {
139 client.login({name: 'user', pass: 'password'}, function (err, res) {
140 if(err) throw err
141 t.ok(res.okay)
142 console.log(res)
143 t.equal(res.name, 'user')
144
145 cont.para([
146 function (cb) {
147 client.get('foo', function (err, value) {
148 if(err) throw err
149 t.equal(value, 1)
150 cb()
151 })
152 },
153 function (cb) {
154 client.put('foo', -1, function (err) {
155 t.ok(err); cb()
156 })
157 },
158 function (cb) {
159 client.del('foo', function (err) {
160 t.ok(err); cb()
161 })
162 },
163 function (cb) {
164 pull(client.read(), pull.collect(function (err, ary) {
165 if(err) throw err
166 t.deepEqual(ary, [
167 {key: 'foo', value: 1},
168 {key: 'bar', value: 2},
169 {key: 'baz', value: 3},
170 ]); cb()
171 }))
172 }
173 ])(function (err) {
174 t.end()
175 })
176 })
177 })
178
179})
180
181tape('multiple sessions at once', function (t) {
182
183 var server1 = createServerAPI(store)
184 var server2 = createServerAPI(store)
185 var admin = createClientAPI()
186 var user = createClientAPI()
187
188 var s1s = server1.createStream()
189 var s2s = server2.createStream()
190 var us = user.createStream()
191 var as = admin.createStream()
192
193 pull(us, s1s, us)
194 pull(as, s2s, as)
195
196 cont.para([
197 function (cb) {
198 user.login({name: 'user', pass: 'password'}, cb)
199 },
200 function (cb) {
201 admin.login({name: 'admin', pass: 'admin'}, cb)
202 }
203 ])(function (err) {
204 if(err) throw err
205
206 user.get('foo', function (err, value) {
207 if(err) throw err
208 t.equal(value, 1)
209 admin.put('foo', 2, function (err) {
210 if(err) throw err
211 user.get('foo', function (err, value) {
212 if(err) throw err
213 t.equal(value, 2)
214 t.end()
215 })
216 })
217 })
218
219 })
220
221})
222
223tape('nested sessions', function (t) {
224 var server = createServerAPI(store)
225 var client = createClientAPI()
226
227 var ss = server.createStream()
228 var cs = client.createStream()
229
230 pull(cs, ss, cs)
231
232 cont.para([
233 function (cb) {
234 client.nested.get('foo', function (err) {
235 t.ok(err); cb()
236 })
237 },
238 function (cb) {
239 client.nested.put('foo', function (err) {
240 t.ok(err); cb()
241 })
242 },
243 function (cb) {
244 client.nested.del('foo', function (err) {
245 t.ok(err); cb()
246 })
247 },
248 function (cb) {
249 pull(client.nested.read(), pull.collect(function (err) {
250 t.ok(err); cb()
251 }))
252 }
253 ])(function (err) {
254 client.login({name: 'nested', pass: 'foofoo'}, function (err, res) {
255 cont.para([
256 function (cb) {
257 client.nested.get('foo', function (err, value) {
258 if(err) throw err
259 t.equal(value, 2, 'foo should be 2')
260 cb()
261 })
262 },
263 function (cb) {
264 client.nested.put('foo', -1, function (err) {
265 t.ok(err); cb()
266 })
267 },
268 function (cb) {
269 client.nested.del('foo', function (err) {
270 t.ok(err); cb()
271 })
272 },
273 function (cb) {
274 pull(client.nested.read(), pull.collect(function (err, ary) {
275 if(err) throw err
276 t.deepEqual(ary, [
277 {key: 'foo', value: 2},
278 {key: 'bar', value: 2},
279 {key: 'baz', value: 3},
280 ]); cb()
281 }))
282 }
283 ])(function (err) {
284
285 t.end()
286 })
287 })
288 })
289
290})