PLT-3412 WebRTC Server side & System Console (#3706)
* WebRTC Server side * WebRTC System Console * Consistency on variable names * Add turn and stun uri validation
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
3b4c9d7588
Коммит
b180bb46e3
@@ -1898,3 +1898,14 @@ func (c *Client) SamlCertificateStatus(filename string) (map[string]interface{},
|
||||
return StringInterfaceFromJson(r.Body), nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetWebrtcToken if Successful returns a map with a valid token, stun server and turn server with credentials to use with
|
||||
// the Mattermost WebRTC service, otherwise returns an AppError. Must be authenticated user.
|
||||
func (c *Client) GetWebrtcToken() (map[string]string, *AppError) {
|
||||
if r, err := c.DoApiPost("/webrtc/token", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
defer closeBody(r)
|
||||
return MapFromJson(r.Body), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,6 +292,17 @@ type NativeAppSettings struct {
|
||||
IosAppDownloadLink *string
|
||||
}
|
||||
|
||||
type WebrtcSettings struct {
|
||||
Enable *bool
|
||||
GatewayWebsocketUrl *string
|
||||
GatewayAdminUrl *string
|
||||
GatewayAdminSecret *string
|
||||
StunURI *string
|
||||
TurnURI *string
|
||||
TurnUsername *string
|
||||
TurnSharedKey *string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
ServiceSettings ServiceSettings
|
||||
TeamSettings TeamSettings
|
||||
@@ -312,6 +323,7 @@ type Config struct {
|
||||
SamlSettings SamlSettings
|
||||
NativeAppSettings NativeAppSettings
|
||||
ClusterSettings ClusterSettings
|
||||
WebrtcSettings WebrtcSettings
|
||||
}
|
||||
|
||||
func (o *Config) ToJson() string {
|
||||
@@ -881,6 +893,8 @@ func (o *Config) SetDefaults() {
|
||||
o.NativeAppSettings.IosAppDownloadLink = new(string)
|
||||
*o.NativeAppSettings.IosAppDownloadLink = "https://about.mattermost.com/mattermost-ios-app/"
|
||||
}
|
||||
|
||||
o.defaultWebrtcSettings()
|
||||
}
|
||||
|
||||
func (o *Config) IsValid() *AppError {
|
||||
@@ -1083,6 +1097,10 @@ func (o *Config) IsValid() *AppError {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.sitename_length.app_error", map[string]interface{}{"MaxLength": SITENAME_MAX_LENGTH}, "")
|
||||
}
|
||||
|
||||
if err := o.isValidWebrtcSettings(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1121,3 +1139,71 @@ func (o *Config) Sanitize() {
|
||||
o.SqlSettings.DataSourceReplicas[i] = FAKE_SETTING
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Config) defaultWebrtcSettings() {
|
||||
if o.WebrtcSettings.Enable == nil {
|
||||
o.WebrtcSettings.Enable = new(bool)
|
||||
*o.WebrtcSettings.Enable = false
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.GatewayWebsocketUrl == nil {
|
||||
o.WebrtcSettings.GatewayWebsocketUrl = new(string)
|
||||
*o.WebrtcSettings.GatewayWebsocketUrl = ""
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.GatewayAdminUrl == nil {
|
||||
o.WebrtcSettings.GatewayAdminUrl = new(string)
|
||||
*o.WebrtcSettings.GatewayAdminUrl = ""
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.GatewayAdminSecret == nil {
|
||||
o.WebrtcSettings.GatewayAdminSecret = new(string)
|
||||
*o.WebrtcSettings.GatewayAdminSecret = ""
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.StunURI == nil {
|
||||
o.WebrtcSettings.StunURI = new(string)
|
||||
*o.WebrtcSettings.StunURI = ""
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.TurnURI == nil {
|
||||
o.WebrtcSettings.TurnURI = new(string)
|
||||
*o.WebrtcSettings.TurnURI = ""
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.TurnUsername == nil {
|
||||
o.WebrtcSettings.TurnUsername = new(string)
|
||||
*o.WebrtcSettings.TurnUsername = ""
|
||||
}
|
||||
|
||||
if o.WebrtcSettings.TurnSharedKey == nil {
|
||||
o.WebrtcSettings.TurnSharedKey = new(string)
|
||||
*o.WebrtcSettings.TurnSharedKey = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Config) isValidWebrtcSettings() *AppError {
|
||||
if *o.WebrtcSettings.Enable {
|
||||
if len(*o.WebrtcSettings.GatewayWebsocketUrl) == 0 || !IsValidWebsocketUrl(*o.WebrtcSettings.GatewayWebsocketUrl) {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_gateway_ws_url.app_error", nil, "")
|
||||
} else if len(*o.WebrtcSettings.GatewayAdminUrl) == 0 || !IsValidHttpUrl(*o.WebrtcSettings.GatewayAdminUrl) {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_gateway_admin_url.app_error", nil, "")
|
||||
} else if len(*o.WebrtcSettings.GatewayAdminSecret) == 0 {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_gateway_admin_secret.app_error", nil, "")
|
||||
} else if len(*o.WebrtcSettings.StunURI) != 0 && !IsValidTurnOrStunServer(*o.WebrtcSettings.StunURI) {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_stun_uri.app_error", nil, "")
|
||||
} else if len(*o.WebrtcSettings.TurnURI) != 0 {
|
||||
if !IsValidTurnOrStunServer(*o.WebrtcSettings.TurnURI) {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_turn_uri.app_error", nil, "")
|
||||
}
|
||||
if len(*o.WebrtcSettings.TurnUsername) == 0 {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_turn_username.app_error", nil, "")
|
||||
} else if len(*o.WebrtcSettings.TurnSharedKey) == 0 {
|
||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.webrtc_turn_shared_key.app_error", nil, "")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -43,7 +43,9 @@ type Features struct {
|
||||
MHPNS *bool `json:"mhpns"`
|
||||
SAML *bool `json:"saml"`
|
||||
PasswordRequirements *bool `json:"password_requirements"`
|
||||
FutureFeatures *bool `json:"future_features"`
|
||||
// after we enabled more features for web rtc we'll need to control them with this
|
||||
Webrtc *bool `json:"webrtc"`
|
||||
FutureFeatures *bool `json:"future_features"`
|
||||
}
|
||||
|
||||
func (f *Features) ToMap() map[string]interface{} {
|
||||
@@ -122,6 +124,11 @@ func (f *Features) SetDefaults() {
|
||||
f.PasswordRequirements = new(bool)
|
||||
*f.PasswordRequirements = *f.FutureFeatures
|
||||
}
|
||||
|
||||
if f.Webrtc == nil {
|
||||
f.Webrtc = new(bool)
|
||||
*f.Webrtc = *f.FutureFeatures
|
||||
}
|
||||
}
|
||||
|
||||
func (l *License) IsExpired() bool {
|
||||
|
||||
@@ -413,6 +413,18 @@ func IsValidHttpsUrl(rawUrl string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func IsValidTurnOrStunServer(rawUri string) bool {
|
||||
if strings.Index(rawUri, "turn:") != 0 && strings.Index(rawUri, "stun:") != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := url.ParseRequestURI(rawUri); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func IsSafeLink(link *string) bool {
|
||||
if link != nil {
|
||||
if IsValidHttpUrl(*link) {
|
||||
@@ -426,3 +438,15 @@ func IsSafeLink(link *string) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func IsValidWebsocketUrl(rawUrl string) bool {
|
||||
if strings.Index(rawUrl, "ws://") != 0 && strings.Index(rawUrl, "wss://") != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := url.ParseRequestURI(rawUrl); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ const (
|
||||
WEBSOCKET_EVENT_EPHEMERAL_MESSAGE = "ephemeral_message"
|
||||
WEBSOCKET_EVENT_STATUS_CHANGE = "status_change"
|
||||
WEBSOCKET_EVENT_HELLO = "hello"
|
||||
WEBSOCKET_EVENT_WEBRTC = "webrtc"
|
||||
)
|
||||
|
||||
type WebSocketMessage interface {
|
||||
|
||||
Ссылка в новой задаче
Block a user