permissionpolicy.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package permissionpolicy
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. )
  7. /*
  8. Permisson Policy
  9. This is a permission policy header modifier that changes
  10. the request permission related policy fields
  11. author: tobychui
  12. */
  13. type PermissionsPolicy struct {
  14. Accelerometer []string `json:"accelerometer"`
  15. AmbientLightSensor []string `json:"ambient_light_sensor"`
  16. Autoplay []string `json:"autoplay"`
  17. Battery []string `json:"battery"`
  18. Camera []string `json:"camera"`
  19. CrossOriginIsolated []string `json:"cross_origin_isolated"`
  20. DisplayCapture []string `json:"display_capture"`
  21. DocumentDomain []string `json:"document_domain"`
  22. EncryptedMedia []string `json:"encrypted_media"`
  23. ExecutionWhileNotRendered []string `json:"execution_while_not_rendered"`
  24. ExecutionWhileOutOfView []string `json:"execution_while_out_of_viewport"`
  25. Fullscreen []string `json:"fullscreen"`
  26. Geolocation []string `json:"geolocation"`
  27. Gyroscope []string `json:"gyroscope"`
  28. KeyboardMap []string `json:"keyboard_map"`
  29. Magnetometer []string `json:"magnetometer"`
  30. Microphone []string `json:"microphone"`
  31. Midi []string `json:"midi"`
  32. NavigationOverride []string `json:"navigation_override"`
  33. Payment []string `json:"payment"`
  34. PictureInPicture []string `json:"picture_in_picture"`
  35. PublicKeyCredentialsGet []string `json:"publickey_credentials_get"`
  36. ScreenWakeLock []string `json:"screen_wake_lock"`
  37. SyncXHR []string `json:"sync_xhr"`
  38. USB []string `json:"usb"`
  39. WebShare []string `json:"web_share"`
  40. XRSpatialTracking []string `json:"xr_spatial_tracking"`
  41. ClipboardRead []string `json:"clipboard_read"`
  42. ClipboardWrite []string `json:"clipboard_write"`
  43. Gamepad []string `json:"gamepad"`
  44. SpeakerSelection []string `json:"speaker_selection"`
  45. ConversionMeasurement []string `json:"conversion_measurement"`
  46. FocusWithoutUserActivation []string `json:"focus_without_user_activation"`
  47. HID []string `json:"hid"`
  48. IdleDetection []string `json:"idle_detection"`
  49. InterestCohort []string `json:"interest_cohort"`
  50. Serial []string `json:"serial"`
  51. SyncScript []string `json:"sync_script"`
  52. TrustTokenRedemption []string `json:"trust_token_redemption"`
  53. Unload []string `json:"unload"`
  54. WindowPlacement []string `json:"window_placement"`
  55. VerticalScroll []string `json:"vertical_scroll"`
  56. }
  57. // GetDefaultPermissionPolicy returns a PermissionsPolicy struct with all policies set to *
  58. func GetDefaultPermissionPolicy() *PermissionsPolicy {
  59. return &PermissionsPolicy{
  60. Accelerometer: []string{"*"},
  61. AmbientLightSensor: []string{"*"},
  62. Autoplay: []string{"*"},
  63. Battery: []string{"*"},
  64. Camera: []string{"*"},
  65. CrossOriginIsolated: []string{"*"},
  66. DisplayCapture: []string{"*"},
  67. DocumentDomain: []string{"*"},
  68. EncryptedMedia: []string{"*"},
  69. ExecutionWhileNotRendered: []string{"*"},
  70. ExecutionWhileOutOfView: []string{"*"},
  71. Fullscreen: []string{"*"},
  72. Geolocation: []string{"*"},
  73. Gyroscope: []string{"*"},
  74. KeyboardMap: []string{"*"},
  75. Magnetometer: []string{"*"},
  76. Microphone: []string{"*"},
  77. Midi: []string{"*"},
  78. NavigationOverride: []string{"*"},
  79. Payment: []string{"*"},
  80. PictureInPicture: []string{"*"},
  81. PublicKeyCredentialsGet: []string{"*"},
  82. ScreenWakeLock: []string{"*"},
  83. SyncXHR: []string{"*"},
  84. USB: []string{"*"},
  85. WebShare: []string{"*"},
  86. XRSpatialTracking: []string{"*"},
  87. ClipboardRead: []string{"*"},
  88. ClipboardWrite: []string{"*"},
  89. Gamepad: []string{"*"},
  90. SpeakerSelection: []string{"*"},
  91. ConversionMeasurement: []string{"*"},
  92. FocusWithoutUserActivation: []string{"*"},
  93. HID: []string{"*"},
  94. IdleDetection: []string{"*"},
  95. InterestCohort: []string{"*"},
  96. Serial: []string{"*"},
  97. SyncScript: []string{"*"},
  98. TrustTokenRedemption: []string{"*"},
  99. Unload: []string{"*"},
  100. WindowPlacement: []string{"*"},
  101. VerticalScroll: []string{"*"},
  102. }
  103. }
  104. // ToKeyValueHeader convert a permission policy struct into a key value string header
  105. func (policy *PermissionsPolicy) ToKeyValueHeader() []string {
  106. policyHeader := []string{}
  107. // Helper function to add policy directives
  108. addDirective := func(name string, sources []string) {
  109. if len(sources) > 0 {
  110. if sources[0] == "*" {
  111. //Allow all
  112. policyHeader = append(policyHeader, fmt.Sprintf("%s=%s", name, "*"))
  113. } else {
  114. //Other than "self" which do not need double quote, others domain need double quote in place
  115. formatedSources := []string{}
  116. for _, source := range sources {
  117. if source == "self" {
  118. formatedSources = append(formatedSources, "self")
  119. } else {
  120. formatedSources = append(formatedSources, "\""+source+"\"")
  121. }
  122. }
  123. policyHeader = append(policyHeader, fmt.Sprintf("%s=(%s)", name, strings.Join(formatedSources, " ")))
  124. }
  125. } else {
  126. //There are no setting for this field. Assume no permission
  127. policyHeader = append(policyHeader, fmt.Sprintf("%s=()", name))
  128. }
  129. }
  130. // Add each policy directive to the header
  131. addDirective("accelerometer", policy.Accelerometer)
  132. addDirective("ambient-light-sensor", policy.AmbientLightSensor)
  133. addDirective("autoplay", policy.Autoplay)
  134. addDirective("battery", policy.Battery)
  135. addDirective("camera", policy.Camera)
  136. addDirective("cross-origin-isolated", policy.CrossOriginIsolated)
  137. addDirective("display-capture", policy.DisplayCapture)
  138. addDirective("document-domain", policy.DocumentDomain)
  139. addDirective("encrypted-media", policy.EncryptedMedia)
  140. addDirective("execution-while-not-rendered", policy.ExecutionWhileNotRendered)
  141. addDirective("execution-while-out-of-viewport", policy.ExecutionWhileOutOfView)
  142. addDirective("fullscreen", policy.Fullscreen)
  143. addDirective("geolocation", policy.Geolocation)
  144. addDirective("gyroscope", policy.Gyroscope)
  145. addDirective("keyboard-map", policy.KeyboardMap)
  146. addDirective("magnetometer", policy.Magnetometer)
  147. addDirective("microphone", policy.Microphone)
  148. addDirective("midi", policy.Midi)
  149. addDirective("navigation-override", policy.NavigationOverride)
  150. addDirective("payment", policy.Payment)
  151. addDirective("picture-in-picture", policy.PictureInPicture)
  152. addDirective("publickey-credentials-get", policy.PublicKeyCredentialsGet)
  153. addDirective("screen-wake-lock", policy.ScreenWakeLock)
  154. addDirective("sync-xhr", policy.SyncXHR)
  155. addDirective("usb", policy.USB)
  156. addDirective("web-share", policy.WebShare)
  157. addDirective("xr-spatial-tracking", policy.XRSpatialTracking)
  158. addDirective("clipboard-read", policy.ClipboardRead)
  159. addDirective("clipboard-write", policy.ClipboardWrite)
  160. addDirective("gamepad", policy.Gamepad)
  161. addDirective("speaker-selection", policy.SpeakerSelection)
  162. addDirective("conversion-measurement", policy.ConversionMeasurement)
  163. addDirective("focus-without-user-activation", policy.FocusWithoutUserActivation)
  164. addDirective("hid", policy.HID)
  165. addDirective("idle-detection", policy.IdleDetection)
  166. addDirective("interest-cohort", policy.InterestCohort)
  167. addDirective("serial", policy.Serial)
  168. addDirective("sync-script", policy.SyncScript)
  169. addDirective("trust-token-redemption", policy.TrustTokenRedemption)
  170. addDirective("unload", policy.Unload)
  171. addDirective("window-placement", policy.WindowPlacement)
  172. addDirective("vertical-scroll", policy.VerticalScroll)
  173. // Join the directives and set the header
  174. policyHeaderValue := strings.Join(policyHeader, ", ")
  175. return []string{"Permissions-Policy", policyHeaderValue}
  176. }
  177. // InjectPermissionPolicyHeader inject the permission policy into headers
  178. func InjectPermissionPolicyHeader(w http.ResponseWriter, policy *PermissionsPolicy) {
  179. //Keep the original Permission Policy if exists, or there are no policy given
  180. if policy == nil || w.Header().Get("Permissions-Policy") != "" {
  181. return
  182. }
  183. headerKV := policy.ToKeyValueHeader()
  184. //Inject the new policy into the header
  185. w.Header().Set(headerKV[0], headerKV[1])
  186. }