From f9a3a4b3949dddecae413b97904c895b2cd887bf Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Wed, 30 Mar 2016 12:49:29 -0400 Subject: Add MFA functionality --- model/client.go | 36 ++++++++++++++++++++++++++++++++++++ model/config.go | 6 ++++++ model/license.go | 6 ++++++ model/user.go | 28 +++++++++++++++++----------- 4 files changed, 65 insertions(+), 11 deletions(-) (limited to 'model') diff --git a/model/client.go b/model/client.go index ee26ae64e..960fe634b 100644 --- a/model/client.go +++ b/model/client.go @@ -301,6 +301,42 @@ func (c *Client) Logout() (*Result, *AppError) { } } +func (c *Client) CheckMfa(method, teamName, loginId string) (*Result, *AppError) { + m := make(map[string]string) + m["method"] = method + m["team_name"] = teamName + m["login_id"] = loginId + + if r, err := c.DoApiPost("/users/mfa", MapToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + +func (c *Client) GenerateMfaQrCode() (*Result, *AppError) { + if r, err := c.DoApiGet("/users/generate_mfa_qr", "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), r.Body}, nil + } +} + +func (c *Client) UpdateMfa(activate bool, token string) (*Result, *AppError) { + m := make(map[string]interface{}) + m["activate"] = activate + m["token"] = token + + if r, err := c.DoApiPost("/users/update_mfa", StringInterfaceToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + func (c *Client) SetOAuthToken(token string) { c.AuthToken = token c.AuthType = HEADER_TOKEN diff --git a/model/config.go b/model/config.go index 3ca241275..e7ab07f8c 100644 --- a/model/config.go +++ b/model/config.go @@ -46,6 +46,7 @@ type ServiceSettings struct { EnableDeveloper *bool EnableSecurityFixAlert *bool EnableInsecureOutgoingConnections *bool + EnableMultifactorAuthentication *bool AllowCorsFrom *string SessionLengthWebInDays *int SessionLengthMobileInDays *int @@ -275,6 +276,11 @@ func (o *Config) SetDefaults() { *o.ServiceSettings.EnableInsecureOutgoingConnections = false } + if o.ServiceSettings.EnableMultifactorAuthentication == nil { + o.ServiceSettings.EnableMultifactorAuthentication = new(bool) + *o.ServiceSettings.EnableMultifactorAuthentication = false + } + if o.TeamSettings.RestrictTeamNames == nil { o.TeamSettings.RestrictTeamNames = new(bool) *o.TeamSettings.RestrictTeamNames = true diff --git a/model/license.go b/model/license.go index 8461c9f76..cab22a685 100644 --- a/model/license.go +++ b/model/license.go @@ -34,6 +34,7 @@ type Customer struct { type Features struct { Users *int `json:"users"` LDAP *bool `json:"ldap"` + MFA *bool `json:"mfa"` GoogleSSO *bool `json:"google_sso"` Compliance *bool `json:"compliance"` } @@ -49,6 +50,11 @@ func (f *Features) SetDefaults() { *f.LDAP = true } + if f.MFA == nil { + f.MFA = new(bool) + *f.MFA = true + } + if f.GoogleSSO == nil { f.GoogleSSO = new(bool) *f.GoogleSSO = true diff --git a/model/user.go b/model/user.go index 675a1ded6..f8f2fdb70 100644 --- a/model/user.go +++ b/model/user.go @@ -15,17 +15,19 @@ import ( ) const ( - ROLE_TEAM_ADMIN = "admin" - ROLE_SYSTEM_ADMIN = "system_admin" - USER_AWAY_TIMEOUT = 5 * 60 * 1000 // 5 minutes - USER_OFFLINE_TIMEOUT = 1 * 60 * 1000 // 1 minute - USER_OFFLINE = "offline" - USER_AWAY = "away" - USER_ONLINE = "online" - USER_NOTIFY_ALL = "all" - USER_NOTIFY_MENTION = "mention" - USER_NOTIFY_NONE = "none" - DEFAULT_LOCALE = "en" + ROLE_TEAM_ADMIN = "admin" + ROLE_SYSTEM_ADMIN = "system_admin" + USER_AWAY_TIMEOUT = 5 * 60 * 1000 // 5 minutes + USER_OFFLINE_TIMEOUT = 1 * 60 * 1000 // 1 minute + USER_OFFLINE = "offline" + USER_AWAY = "away" + USER_ONLINE = "online" + USER_NOTIFY_ALL = "all" + USER_NOTIFY_MENTION = "mention" + USER_NOTIFY_NONE = "none" + DEFAULT_LOCALE = "en" + USER_AUTH_SERVICE_EMAIL = "email" + USER_AUTH_SERVICE_USERNAME = "username" ) type User struct { @@ -54,6 +56,8 @@ type User struct { LastPictureUpdate int64 `json:"last_picture_update,omitempty"` FailedAttempts int `json:"failed_attempts,omitempty"` Locale string `json:"locale"` + MfaActive bool `json:"mfa_active,omitempty"` + MfaSecret string `json:"mfa_secret,omitempty"` } // IsValid validates the user and returns an error if it isn't configured @@ -140,6 +144,8 @@ func (u *User) PreSave() { u.LastPasswordUpdate = u.CreateAt + u.MfaActive = false + if u.Locale == "" { u.Locale = DEFAULT_LOCALE } -- cgit v1.2.3-1-g7c22