github.com/whoyao/protocol@v0.0.0-20230519045905-2d8ace718ca5/auth/grants.go (about) 1 package auth 2 3 import ( 4 "strings" 5 6 "golang.org/x/exp/slices" 7 8 "github.com/whoyao/protocol/livekit" 9 ) 10 11 type VideoGrant struct { 12 // actions on rooms 13 RoomCreate bool `json:"roomCreate,omitempty"` 14 RoomList bool `json:"roomList,omitempty"` 15 RoomRecord bool `json:"roomRecord,omitempty"` 16 17 // actions on a particular room 18 RoomAdmin bool `json:"roomAdmin,omitempty"` 19 RoomJoin bool `json:"roomJoin,omitempty"` 20 Room string `json:"room,omitempty"` 21 22 // permissions within a room, if none of the permissions are set explicitly 23 // it will be granted with all publish and subscribe permissions 24 CanPublish *bool `json:"canPublish,omitempty"` 25 CanSubscribe *bool `json:"canSubscribe,omitempty"` 26 CanPublishData *bool `json:"canPublishData,omitempty"` 27 // TrackSource types that a participant may publish. 28 // When set, it supersedes CanPublish. Only sources explicitly set here can be published 29 CanPublishSources []string `json:"canPublishSources,omitempty"` // keys keep track of each source 30 // by default, a participant is not allowed to update its own metadata 31 CanUpdateOwnMetadata *bool `json:"canUpdateOwnMetadata,omitempty"` 32 33 // actions on ingresses 34 IngressAdmin bool `json:"ingressAdmin,omitempty"` // applies to all ingress 35 36 // participant is not visible to other participants 37 Hidden bool `json:"hidden,omitempty"` 38 // indicates to the room that current participant is a recorder 39 Recorder bool `json:"recorder,omitempty"` 40 } 41 42 type ClaimGrants struct { 43 Identity string `json:"-"` 44 Name string `json:"name,omitempty"` 45 Video *VideoGrant `json:"video,omitempty"` 46 // for verifying integrity of the message body 47 Sha256 string `json:"sha256,omitempty"` 48 Metadata string `json:"metadata,omitempty"` 49 } 50 51 func (c *ClaimGrants) Clone() *ClaimGrants { 52 if c == nil { 53 return nil 54 } 55 56 clone := *c 57 clone.Video = c.Video.Clone() 58 59 return &clone 60 } 61 62 func (v *VideoGrant) SetCanPublish(val bool) { 63 v.CanPublish = &val 64 } 65 66 func (v *VideoGrant) SetCanPublishData(val bool) { 67 v.CanPublishData = &val 68 } 69 70 func (v *VideoGrant) SetCanSubscribe(val bool) { 71 v.CanSubscribe = &val 72 } 73 74 func (v *VideoGrant) SetCanPublishSources(sources []livekit.TrackSource) { 75 v.CanPublishSources = make([]string, 0, len(sources)) 76 for _, s := range sources { 77 v.CanPublishSources = append(v.CanPublishSources, sourceToString(s)) 78 } 79 } 80 81 func (v *VideoGrant) SetCanUpdateOwnMetadata(val bool) { 82 v.CanUpdateOwnMetadata = &val 83 } 84 85 func (v *VideoGrant) GetCanPublish() bool { 86 if v.CanPublish == nil { 87 return true 88 } 89 return *v.CanPublish 90 } 91 92 func (v *VideoGrant) GetCanPublishSource(source livekit.TrackSource) bool { 93 if !v.GetCanPublish() { 94 return false 95 } 96 // don't differentiate between nil and unset, since that distinction doesn't survive serialization 97 if len(v.CanPublishSources) == 0 { 98 return true 99 } 100 sourceStr := sourceToString(source) 101 for _, s := range v.CanPublishSources { 102 if s == sourceStr { 103 return true 104 } 105 } 106 return false 107 } 108 109 func (v *VideoGrant) GetCanPublishSources() []livekit.TrackSource { 110 if len(v.CanPublishSources) == 0 { 111 return nil 112 } 113 114 sources := make([]livekit.TrackSource, 0, len(v.CanPublishSources)) 115 for _, s := range v.CanPublishSources { 116 sources = append(sources, sourceToProto(s)) 117 } 118 return sources 119 } 120 121 func (v *VideoGrant) GetCanPublishData() bool { 122 if v.CanPublishData == nil { 123 return v.GetCanPublish() 124 } 125 return *v.CanPublishData 126 } 127 128 func (v *VideoGrant) GetCanSubscribe() bool { 129 if v.CanSubscribe == nil { 130 return true 131 } 132 return *v.CanSubscribe 133 } 134 135 func (v *VideoGrant) GetCanUpdateOwnMetadata() bool { 136 if v.CanUpdateOwnMetadata == nil { 137 return false 138 } 139 return *v.CanUpdateOwnMetadata 140 } 141 142 func (v *VideoGrant) MatchesPermission(permission *livekit.ParticipantPermission) bool { 143 if permission == nil { 144 return false 145 } 146 147 if v.GetCanPublish() != permission.CanPublish { 148 return false 149 } 150 if v.GetCanPublishData() != permission.CanPublishData { 151 return false 152 } 153 if v.GetCanSubscribe() != permission.CanSubscribe { 154 return false 155 } 156 if v.GetCanUpdateOwnMetadata() != permission.CanUpdateMetadata { 157 return false 158 } 159 if v.Hidden != permission.Hidden { 160 return false 161 } 162 if v.Recorder != permission.Recorder { 163 return false 164 } 165 if !slices.Equal(v.GetCanPublishSources(), permission.CanPublishSources) { 166 return false 167 } 168 169 return true 170 } 171 172 func (v *VideoGrant) UpdateFromPermission(permission *livekit.ParticipantPermission) { 173 if permission == nil { 174 return 175 } 176 177 v.SetCanPublish(permission.CanPublish) 178 v.SetCanPublishData(permission.CanPublishData) 179 v.SetCanPublishSources(permission.CanPublishSources) 180 v.SetCanSubscribe(permission.CanSubscribe) 181 v.SetCanUpdateOwnMetadata(permission.CanUpdateMetadata) 182 v.Hidden = permission.Hidden 183 v.Recorder = permission.Recorder 184 } 185 186 func (v *VideoGrant) ToPermission() *livekit.ParticipantPermission { 187 pp := &livekit.ParticipantPermission{ 188 CanPublish: v.GetCanPublish(), 189 CanPublishData: v.GetCanPublishData(), 190 CanSubscribe: v.GetCanSubscribe(), 191 CanPublishSources: v.GetCanPublishSources(), 192 CanUpdateMetadata: v.GetCanUpdateOwnMetadata(), 193 Hidden: v.Hidden, 194 Recorder: v.Recorder, 195 } 196 return pp 197 } 198 199 func (v *VideoGrant) Clone() *VideoGrant { 200 if v == nil { 201 return nil 202 } 203 204 clone := *v 205 206 if v.CanPublish != nil { 207 canPublish := *v.CanPublish 208 clone.CanPublish = &canPublish 209 } 210 211 if v.CanSubscribe != nil { 212 canSubscribe := *v.CanSubscribe 213 clone.CanSubscribe = &canSubscribe 214 } 215 216 if v.CanPublishData != nil { 217 canPublishData := *v.CanPublishData 218 clone.CanPublishData = &canPublishData 219 } 220 221 if v.CanPublishSources != nil { 222 clone.CanPublishSources = make([]string, len(v.CanPublishSources)) 223 copy(clone.CanPublishSources, v.CanPublishSources) 224 } 225 226 if v.CanUpdateOwnMetadata != nil { 227 canUpdateOwnMetadata := *v.CanUpdateOwnMetadata 228 clone.CanUpdateOwnMetadata = &canUpdateOwnMetadata 229 } 230 231 return &clone 232 } 233 234 func sourceToString(source livekit.TrackSource) string { 235 return strings.ToLower(source.String()) 236 } 237 238 func sourceToProto(sourceStr string) livekit.TrackSource { 239 switch sourceStr { 240 case "camera": 241 return livekit.TrackSource_CAMERA 242 case "microphone": 243 return livekit.TrackSource_MICROPHONE 244 case "screen_share": 245 return livekit.TrackSource_SCREEN_SHARE 246 case "screen_share_audio": 247 return livekit.TrackSource_SCREEN_SHARE_AUDIO 248 default: 249 return livekit.TrackSource_UNKNOWN 250 } 251 }