permissions.mx raw
1 package main
2
3 import (
4 "git.smesh.lol/musiquay/web/common/helpers"
5 "git.smesh.lol/musiquay/web/common/jsbridge/ext"
6 )
7
8 // Per-host, per-method permission store.
9 // Policies: "allow", "deny", "ask" (default when not set).
10
11 type permission struct {
12 Host string
13 Method string
14 Policy string
15 }
16
17
18 func loadPermissions() {
19 ext.StorageGet(permsStorageKey, func(data string) {
20 if data != "" {
21 parsePermissions(data)
22 }
23 })
24 }
25
26 func getPermission(host, method string) (s string) {
27 for _, p := range signSt.permissions {
28 if p.Host == host && p.Method == method {
29 return p.Policy
30 }
31 }
32 return "ask"
33 }
34
35 func setPermission(host, method, policy string) {
36 for i, p := range signSt.permissions {
37 if p.Host == host && p.Method == method {
38 signSt.permissions[i].Policy = policy
39 savePermissions()
40 return
41 }
42 }
43 signSt.permissions = push(signSt.permissions, permission{Host: host, Method: method, Policy: policy})
44 savePermissions()
45 }
46
47 func savePermissions() {
48 b := push([]byte(nil), '[')
49 for i, p := range signSt.permissions {
50 if i > 0 {
51 b = b | ","
52 }
53 b = b | "{\"host\":"
54 b = b | helpers.JsonString(p.Host)
55 b = b | ",\"method\":"
56 b = b | helpers.JsonString(p.Method)
57 b = b | ",\"policy\":"
58 b = b | helpers.JsonString(p.Policy)
59 b = b | "}"
60 }
61 ext.StorageSet(permsStorageKey, string(b | "]"))
62 }
63
64 func parsePermissions(s string) {
65 signSt.permissions = nil
66 i := 0
67 for i < len(s) && s[i] != '[' {
68 i++
69 }
70 i++
71 for i < len(s) {
72 for i < len(s) && s[i] != '{' && s[i] != ']' {
73 i++
74 }
75 if i >= len(s) || s[i] == ']' {
76 break
77 }
78 end := i + 1
79 depth := 1
80 for end < len(s) && depth > 0 {
81 if s[end] == '{' {
82 depth++
83 } else if s[end] == '}' {
84 depth--
85 } else if s[end] == '"' {
86 end++
87 for end < len(s) && s[end] != '"' {
88 if s[end] == '\\' {
89 end++
90 }
91 end++
92 }
93 }
94 end++
95 }
96 obj := s[i:end]
97 kHost := string(push([]byte(nil), 'h', 'o', 's', 't'))
98 kMethod := string(push([]byte(nil), 'm', 'e', 't', 'h', 'o', 'd'))
99 kPolicy := string(push([]byte(nil), 'p', 'o', 'l', 'i', 'c', 'y'))
100 host := helpers.JsonGetString(obj, kHost)
101 method := helpers.JsonGetString(obj, kMethod)
102 policy := helpers.JsonGetString(obj, kPolicy)
103 if host != "" && method != "" && policy != "" {
104 signSt.permissions = push(signSt.permissions, permission{Host: host, Method: method, Policy: policy})
105 }
106 i = end
107 }
108 }
109
110 func mgmtGetPermissions() (s string) {
111 b := push([]byte(nil), '{', '"', 'r', 'e', 's', 'u', 'l', 't', '"', ':', '[')
112 for i, p := range signSt.permissions {
113 if i > 0 {
114 b = b | ","
115 }
116 b = b | "{\"host\":"
117 b = b | helpers.JsonString(p.Host)
118 b = b | ",\"method\":"
119 b = b | helpers.JsonString(p.Method)
120 b = b | ",\"policy\":"
121 b = b | helpers.JsonString(p.Policy)
122 b = b | "}"
123 }
124 return string(b | "]}")
125 }
126
127 func mgmtSetPermission(paramsJSON string) (s string) {
128 kHost := string(push([]byte(nil), 'h', 'o', 's', 't'))
129 kMethod := string(push([]byte(nil), 'm', 'e', 't', 'h', 'o', 'd'))
130 kPolicy := string(push([]byte(nil), 'p', 'o', 'l', 'i', 'c', 'y'))
131 host := helpers.JsonGetString(paramsJSON, kHost)
132 method := helpers.JsonGetString(paramsJSON, kMethod)
133 policy := helpers.JsonGetString(paramsJSON, kPolicy)
134 if host == "" || method == "" || policy == "" {
135 return jsonErr(string(push([]byte(nil), 'm', 'i', 's', 's', 'i', 'n', 'g', ' ', 'p', 'a', 'r', 'a', 'm', 's')))
136 }
137 setPermission(host, method, policy)
138 return jsonTrue()
139 }
140
141 func mgmtPromptResponse(paramsJSON string) (s string) {
142 // TODO: handle pending prompt callbacks from content script
143 return jsonFalse()
144 }
145