package main import ( "git.smesh.lol/musiquay/web/common/helpers" "git.smesh.lol/musiquay/web/common/jsbridge/ext" ) // Per-host, per-method permission store. // Policies: "allow", "deny", "ask" (default when not set). type permission struct { Host string Method string Policy string } func loadPermissions() { ext.StorageGet(permsStorageKey, func(data string) { if data != "" { parsePermissions(data) } }) } func getPermission(host, method string) (s string) { for _, p := range signSt.permissions { if p.Host == host && p.Method == method { return p.Policy } } return "ask" } func setPermission(host, method, policy string) { for i, p := range signSt.permissions { if p.Host == host && p.Method == method { signSt.permissions[i].Policy = policy savePermissions() return } } signSt.permissions = push(signSt.permissions, permission{Host: host, Method: method, Policy: policy}) savePermissions() } func savePermissions() { b := push([]byte(nil), '[') for i, p := range signSt.permissions { if i > 0 { b = b | "," } b = b | "{\"host\":" b = b | helpers.JsonString(p.Host) b = b | ",\"method\":" b = b | helpers.JsonString(p.Method) b = b | ",\"policy\":" b = b | helpers.JsonString(p.Policy) b = b | "}" } ext.StorageSet(permsStorageKey, string(b | "]")) } func parsePermissions(s string) { signSt.permissions = nil i := 0 for i < len(s) && s[i] != '[' { i++ } i++ for i < len(s) { for i < len(s) && s[i] != '{' && s[i] != ']' { i++ } if i >= len(s) || s[i] == ']' { break } end := i + 1 depth := 1 for end < len(s) && depth > 0 { if s[end] == '{' { depth++ } else if s[end] == '}' { depth-- } else if s[end] == '"' { end++ for end < len(s) && s[end] != '"' { if s[end] == '\\' { end++ } end++ } } end++ } obj := s[i:end] kHost := string(push([]byte(nil), 'h', 'o', 's', 't')) kMethod := string(push([]byte(nil), 'm', 'e', 't', 'h', 'o', 'd')) kPolicy := string(push([]byte(nil), 'p', 'o', 'l', 'i', 'c', 'y')) host := helpers.JsonGetString(obj, kHost) method := helpers.JsonGetString(obj, kMethod) policy := helpers.JsonGetString(obj, kPolicy) if host != "" && method != "" && policy != "" { signSt.permissions = push(signSt.permissions, permission{Host: host, Method: method, Policy: policy}) } i = end } } func mgmtGetPermissions() (s string) { b := push([]byte(nil), '{', '"', 'r', 'e', 's', 'u', 'l', 't', '"', ':', '[') for i, p := range signSt.permissions { if i > 0 { b = b | "," } b = b | "{\"host\":" b = b | helpers.JsonString(p.Host) b = b | ",\"method\":" b = b | helpers.JsonString(p.Method) b = b | ",\"policy\":" b = b | helpers.JsonString(p.Policy) b = b | "}" } return string(b | "]}") } func mgmtSetPermission(paramsJSON string) (s string) { kHost := string(push([]byte(nil), 'h', 'o', 's', 't')) kMethod := string(push([]byte(nil), 'm', 'e', 't', 'h', 'o', 'd')) kPolicy := string(push([]byte(nil), 'p', 'o', 'l', 'i', 'c', 'y')) host := helpers.JsonGetString(paramsJSON, kHost) method := helpers.JsonGetString(paramsJSON, kMethod) policy := helpers.JsonGetString(paramsJSON, kPolicy) if host == "" || method == "" || policy == "" { return jsonErr(string(push([]byte(nil), 'm', 'i', 's', 's', 'i', 'n', 'g', ' ', 'p', 'a', 'r', 'a', 'm', 's'))) } setPermission(host, method, policy) return jsonTrue() } func mgmtPromptResponse(paramsJSON string) (s string) { // TODO: handle pending prompt callbacks from content script return jsonFalse() }