0.0.4
[henge/kiak.git] / src / strapp.js
1 /**
2 * @file Strapp main driver
3 * @author Jordan Lavatai, Ken Grimes
4 * @version 0.0.4
5 * @license AGPL-3.0
6 * @copyright August 2017 - Ken Grimes, Jordan Lavatai
7 * @summmary Bootstrapper for the strapp.io mechanism
8 */
9
10 const StrappFile = (() => {
11 const authorize = (pubKey, mode, stat) => {
12 let allowed
13 if (pubKey === stat.owner)
14 allowed = (stat.perms >>> 16) & 0xF
15 else {
16 let gAccess = false
17 let uGroups = StrappFile.get(`acct/${pubKey}/groups`).split(' ')
18 for (let i = 0; i < uGroups.length; i++) {
19 if (uGroups[i] === stat.group) {
20 gAccess = true
21 break
22 }
23 }
24 if (gAccess)
25 allowed = (stat.perms >>> 8) & 0xF
26 else
27 allowed = stat.perms & 0xF
28 }
29 switch(mode){
30 case 'r+':
31 case 'rw':
32 case 'wr':
33 return (allowed & 0x6) === 0x6
34 case 'w':
35 return (allowed & 0x2) === 0x2
36 case 'r':
37 return (allowed & 0x4) === 0x4
38 case 'x':
39 return (allowed & 0x1) === 0x1
40 default:
41 console.log(`Unknown access mode: ${mode}`)
42 return false
43 }
44 }
45 class StrappFile extends Object {
46 constructor(...props) {
47 super()
48 return Object.assign(this, new.target.defaults, ...props)
49 }
50 static PermissionDenied() {
51 return new Promise((resolve, reject) => reject('Permission denied'))
52 }
53 HEAD(opt) {
54 if (authorize(opt.pubKey, 'r', this.stat))
55 return new Promise((resolve, reject) => resolve(''))
56 else
57 return StrappFile.PermissionDenied()
58 }
59 GET(opt) {
60 if (authorize(opt.pubKey, 'r', this.stat))
61 return StrappFile.get(this.path)
62 else return StrappFile.PermissionDenied()
63 }
64 PUT(opt) {
65 if (authorize(opt.pubKey, 'w', this.stat))
66 return StrappFile.set(this.path, opt.data)
67 else return StrappFile.PermissionDenied()
68 }
69 POST(opt) {
70 return this.PUT(Object.assign(opt, { data: this.GET(opt) + opt.data }))
71 }
72 DELETE(opt) {
73 if (authorize(opt.pubKey, 'w', this.stat))
74 return StrappFile.delete(this.path)
75 else return StrappFile.PermissionDenied()
76 }
77 OPTIONS(opt) {
78 return this.stat
79 }
80 CONNECT(opt) {
81 return this.GET(opt)
82 }
83 TRACE(opt) {
84 }
85 PATCH(opt) {
86 }
87 }
88 StrappFile.defaults = {
89 type: 'mime/type',
90 perm: 0,
91 owner: 'thisOwnerPubKey',
92 group: 'groupname',
93 changed: 'time',
94 created: 'time',
95 accessed: 'time - not saved'
96 }
97 return StrappFile
98 })()