permission.go RawHistoryFolder
1package entity
2
3// DomainTimestamp represents a Unix timestamp in seconds.
4// This is a domain-owned type to avoid importing time in the domain layer.
5
6// PermissionType represents the type of permission being requested.
7type PermissionType string
8
9const (
10 // PermissionTypeMicrophone represents microphone access permission.
11 PermissionTypeMicrophone PermissionType = "microphone"
12
13 // PermissionTypeCamera represents camera access permission.
14 PermissionTypeCamera PermissionType = "camera"
15
16 // PermissionTypeDisplay represents screen sharing/display capture permission.
17 PermissionTypeDisplay PermissionType = "display"
18
19 // PermissionTypeDeviceInfo represents device enumeration permission.
20 PermissionTypeDeviceInfo PermissionType = "device_info"
21
22 // PermissionTypeClipboard represents clipboard access permission.
23 PermissionTypeClipboard PermissionType = "clipboard"
24
25 // PermissionTypeNotification represents notification permission.
26 PermissionTypeNotification PermissionType = "notification"
27
28 // PermissionTypeGeolocation represents geolocation permission.
29 PermissionTypeGeolocation PermissionType = "geolocation"
30
31 // PermissionTypePointerLock represents pointer lock permission.
32 PermissionTypePointerLock PermissionType = "pointer_lock"
33
34 // PermissionTypeMediaKeySystem represents DRM/media key system permission.
35 PermissionTypeMediaKeySystem PermissionType = "media_key_system"
36
37 // PermissionTypeWebsiteDataAccess represents 3rd party cookie/data access permission.
38 PermissionTypeWebsiteDataAccess PermissionType = "website_data_access"
39)
40
41// Metadata keys for PermissionMetadata.
42const (
43 // PermissionMetadataKeyRequestingDomain is the origin that is requesting cross-site
44 // data access (i.e. the third-party domain asking for its cookies/storage).
45 PermissionMetadataKeyRequestingDomain = "requesting_domain"
46
47 // PermissionMetadataKeyCurrentDomain is the first-party domain currently loaded in
48 // the WebView — the context in which the cross-site request is happening.
49 PermissionMetadataKeyCurrentDomain = "current_domain"
50
51 // PermissionMetadataKeyUnmediatedCapture is set to PermissionMetadataValueTrue when no
52 // system picker/portal will mediate a display capture grant, i.e. allowing the request
53 // shares the entire screen immediately (CEF). It disables display auto-allow.
54 PermissionMetadataKeyUnmediatedCapture = "unmediated_capture"
55
56 // PermissionMetadataKeyUnmediatedAudio is set to PermissionMetadataValueTrue when the
57 // request also captures system (desktop) audio, which no system UI mediates either.
58 PermissionMetadataKeyUnmediatedAudio = "unmediated_audio"
59
60 // PermissionMetadataValueTrue is the metadata value for boolean flags.
61 PermissionMetadataValueTrue = "true"
62)
63
64// PermissionMetadata carries extra context for specific permission types.
65// For website_data_access, callers must populate both keys:
66// - PermissionMetadataKeyRequestingDomain: the origin requesting cross-site data access
67// - PermissionMetadataKeyCurrentDomain: the domain currently loaded in the WebView
68type PermissionMetadata map[string]string
69
70// PermissionDecision represents the user's decision for a permission.
71type PermissionDecision string
72
73const (
74 // PermissionGranted means the permission was allowed.
75 PermissionGranted PermissionDecision = "granted"
76
77 // PermissionDenied means the permission was denied.
78 PermissionDenied PermissionDecision = "denied"
79
80 // PermissionPrompt means no decision has been made yet (default state).
81 PermissionPrompt PermissionDecision = "prompt"
82)
83
84// PermissionRecord stores a permission decision for a specific origin and type.
85type PermissionRecord struct {
86 Origin string // The origin (domain) this permission applies to
87 Type PermissionType // The type of permission
88 Decision PermissionDecision // The decision: granted, denied, or prompt
89 UpdatedAt int64 // Unix timestamp in seconds when this record was last updated
90}
91
92// IsGranted returns true if the permission is granted.
93func (p *PermissionRecord) IsGranted() bool {
94 return p.Decision == PermissionGranted
95}
96
97// IsDenied returns true if the permission is denied.
98func (p *PermissionRecord) IsDenied() bool {
99 return p.Decision == PermissionDenied
100}
101
102// PermissionSet represents multiple permission decisions for a single request.
103// This is used when handling combined permission requests (e.g., mic + camera).
104type PermissionSet struct {
105 Types []PermissionType
106 Decision PermissionDecision
107}
108
109// CanPersist returns true if this permission type can be persisted.
110// Per W3C spec, display capture permissions cannot be persisted.
111func CanPersist(permType PermissionType) bool {
112 switch permType {
113 case PermissionTypeDisplay:
114 return false // W3C forbids persisting display capture permissions
115 case PermissionTypeDeviceInfo, PermissionTypePointerLock:
116 return false // Auto-allowed, no need to persist
117 default:
118 return true
119 }
120}
121
122// IsUnmediatedCapture reports whether the metadata flags a display capture that no
123// system picker/portal mediates.
124func (m PermissionMetadata) IsUnmediatedCapture() bool {
125 return m[PermissionMetadataKeyUnmediatedCapture] == PermissionMetadataValueTrue
126}
127
128// IsUnmediatedAudio reports whether the metadata flags system audio capture.
129func (m PermissionMetadata) IsUnmediatedAudio() bool {
130 return m[PermissionMetadataKeyUnmediatedAudio] == PermissionMetadataValueTrue
131}
132
133// IsAutoAllowFor is IsAutoAllow with request metadata taken into account: an
134// unmediated display capture is never auto-allowed.
135func IsAutoAllowFor(permType PermissionType, metadata PermissionMetadata) bool {
136 if permType == PermissionTypeDisplay && metadata.IsUnmediatedCapture() {
137 return false
138 }
139 return IsAutoAllow(permType)
140}
141
142// IsAutoAllow returns true if this permission type should be auto-allowed.
143// Exception: display capture is only auto-allowed when a system picker/portal
144// mediates it (WebKit); use IsAutoAllowFor for requests that may carry
145// PermissionMetadataKeyUnmediatedCapture (CEF), which must prompt the user.
146func IsAutoAllow(permType PermissionType) bool {
147 switch permType {
148 case PermissionTypeDisplay:
149 return true // Portal handles the UI
150 case PermissionTypeDeviceInfo:
151 return true // Low risk, just lists devices
152 case PermissionTypePointerLock:
153 return true // Low risk, default WebKit behavior
154 default:
155 return false
156 }
157}
158
159// PermissionTypesToStrings converts permission types to strings for logging.
160func PermissionTypesToStrings(types []PermissionType) []string {
161 result := make([]string, len(types))
162 for i, t := range types {
163 result[i] = string(t)
164 }
165 return result
166}