0.0.4
[henge/kiak.git] / src / strapp.js
diff --git a/src/strapp.js b/src/strapp.js
new file mode 100644 (file)
index 0000000..9ec9d09
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+* @file      Strapp main driver
+* @author    Jordan Lavatai, Ken Grimes
+* @version   0.0.4
+* @license   AGPL-3.0
+* @copyright August 2017 - Ken Grimes, Jordan Lavatai
+* @summmary  Bootstrapper for the strapp.io mechanism
+*/
+
+const StrappFile = (() => {
+  const authorize = (pubKey, mode, stat) => {
+    let allowed
+    if (pubKey === stat.owner)
+      allowed = (stat.perms >>> 16) & 0xF
+    else {
+      let gAccess = false
+      let uGroups = StrappFile.get(`acct/${pubKey}/groups`).split(' ')
+      for (let i = 0; i < uGroups.length; i++) {
+        if (uGroups[i] === stat.group) {
+          gAccess = true
+          break
+        }
+      }
+      if (gAccess)
+        allowed = (stat.perms >>> 8) & 0xF
+      else
+        allowed = stat.perms & 0xF
+    }
+    switch(mode){
+    case 'r+':
+    case 'rw':
+    case 'wr':
+      return (allowed & 0x6) === 0x6
+    case 'w':
+      return (allowed & 0x2) === 0x2
+    case 'r':
+      return (allowed & 0x4) === 0x4
+    case 'x':
+      return (allowed & 0x1) === 0x1
+    default:
+      console.log(`Unknown access mode: ${mode}`)
+      return false
+    }
+  }
+  class StrappFile extends Object {
+    constructor(...props) {
+      super()
+      return Object.assign(this, new.target.defaults, ...props)
+    }
+    static PermissionDenied() {
+      return new Promise((resolve, reject) => reject('Permission denied'))
+    }
+    HEAD(opt) {
+      if (authorize(opt.pubKey, 'r', this.stat))
+        return new Promise((resolve, reject) => resolve(''))
+      else
+        return StrappFile.PermissionDenied()
+    }
+    GET(opt) {
+      if (authorize(opt.pubKey, 'r', this.stat))
+        return StrappFile.get(this.path)
+      else return StrappFile.PermissionDenied()
+    }
+    PUT(opt) {
+      if (authorize(opt.pubKey, 'w', this.stat))
+        return StrappFile.set(this.path, opt.data)
+      else return StrappFile.PermissionDenied()
+    }
+    POST(opt) {
+      return this.PUT(Object.assign(opt, { data: this.GET(opt) + opt.data }))
+    }
+    DELETE(opt) {
+      if (authorize(opt.pubKey, 'w', this.stat))
+        return StrappFile.delete(this.path)
+      else return StrappFile.PermissionDenied()
+    }
+    OPTIONS(opt) {
+      return this.stat
+    }
+    CONNECT(opt) {
+      return this.GET(opt)
+    }
+    TRACE(opt) {
+    }
+    PATCH(opt) {
+    }
+  }
+  StrappFile.defaults = {
+    type: 'mime/type',
+    perm: 0,
+    owner: 'thisOwnerPubKey',
+    group: 'groupname',
+    changed: 'time',
+    created: 'time',
+    accessed: 'time - not saved'
+  }
+  return StrappFile
+})()