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