package main import ( "git.smesh.lol/smesh/web/common/helpers" "git.smesh.lol/smesh/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 } var permissions []permission func loadPermissions() { kPerms := string(append([]byte(nil), 's', 'm', 'e', 's', 'h', '-', 'p', 'e', 'r', 'm', 'i', 's', 's', 'i', 'o', 'n', 's')) ext.StorageGet(kPerms, func(data string) { if data != "" { parsePermissions(data) } }) } func getPermission(host, method string) (s string) { for _, p := range permissions { if p.Host == host && p.Method == method { return p.Policy } } return "ask" } func setPermission(host, method, policy string) { for i, p := range permissions { if p.Host == host && p.Method == method { permissions[i].Policy = policy savePermissions() return } } permissions = append(permissions, permission{Host: host, Method: method, Policy: policy}) savePermissions() } func savePermissions() { b := append([]byte(nil), '[') for i, p := range permissions { if i > 0 { b = append(b, ',') } b = append(b, '{', '"', 'h', 'o', 's', 't', '"', ':') b = b | helpers.JsonString(p.Host) b = append(b, ',', '"', 'm', 'e', 't', 'h', 'o', 'd', '"', ':') b = b | helpers.JsonString(p.Method) b = append(b, ',', '"', 'p', 'o', 'l', 'i', 'c', 'y', '"', ':') b = b | helpers.JsonString(p.Policy) b = append(b, '}') } kPerms := string(append([]byte(nil), 's', 'm', 'e', 's', 'h', '-', 'p', 'e', 'r', 'm', 'i', 's', 's', 'i', 'o', 'n', 's')) ext.StorageSet(kPerms, string(append(b, ']'))) } func parsePermissions(s string) { 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(append([]byte(nil), 'h', 'o', 's', 't')) kMethod := string(append([]byte(nil), 'm', 'e', 't', 'h', 'o', 'd')) kPolicy := string(append([]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 != "" { permissions = append(permissions, permission{Host: host, Method: method, Policy: policy}) } i = end } } func mgmtGetPermissions() (s string) { b := append([]byte(nil), '{', '"', 'r', 'e', 's', 'u', 'l', 't', '"', ':', '[') for i, p := range permissions { if i > 0 { b = append(b, ',') } b = append(b, '{', '"', 'h', 'o', 's', 't', '"', ':') b = b | helpers.JsonString(p.Host) b = append(b, ',', '"', 'm', 'e', 't', 'h', 'o', 'd', '"', ':') b = b | helpers.JsonString(p.Method) b = append(b, ',', '"', 'p', 'o', 'l', 'i', 'c', 'y', '"', ':') b = b | helpers.JsonString(p.Policy) b = append(b, '}') } return string(append(b, ']', '}')) } func mgmtSetPermission(paramsJSON string) (s string) { kHost := string(append([]byte(nil), 'h', 'o', 's', 't')) kMethod := string(append([]byte(nil), 'm', 'e', 't', 'h', 'o', 'd')) kPolicy := string(append([]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(append([]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() }