Invite salt fix for 3.8 (#6149)

This commit is contained in:
Christopher Speller
2017-04-21 15:24:44 -04:00
parent e1c140f949
commit 247cd1e51a
10 changed files with 39 additions and 30 deletions
+6 -5
View File
@@ -200,7 +200,7 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
}
authData := &model.AuthData{UserId: c.Session.UserId, ClientId: clientId, CreateAt: model.GetMillis(), RedirectUri: redirectUri, State: state, Scope: scope}
authData.Code = model.HashPassword(fmt.Sprintf("%v:%v:%v:%v", clientId, redirectUri, authData.CreateAt, c.Session.UserId))
authData.Code = model.HashSha256(fmt.Sprintf("%v:%v:%v:%v", clientId, redirectUri, authData.CreateAt, c.Session.UserId))
// this saves the OAuth2 app as authorized
authorizedApp := model.Preference{
@@ -501,7 +501,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !model.ComparePassword(code, fmt.Sprintf("%v:%v:%v:%v", clientId, redirectUri, authData.CreateAt, authData.UserId)) {
if code != model.HashSha256(fmt.Sprintf("%v:%v:%v:%v", clientId, redirectUri, authData.CreateAt, authData.UserId)) {
c.LogAudit("fail - auth code is invalid")
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.expired_code.app_error", nil, "")
return
@@ -565,6 +565,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
<-app.Srv.Store.OAuth().RemoveAuthData(authData.Code)
} else {
// when grantType is refresh_token
fmt.Printf(refreshToken)
if result := <-app.Srv.Store.OAuth().GetAccessDataByRefreshToken(refreshToken); result.Err != nil {
c.LogAudit("fail - refresh token is invalid")
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.refresh_token.app_error", nil, "")
@@ -636,7 +637,7 @@ func getTeamIdFromQuery(query url.Values) (string, *model.AppError) {
data := query.Get("d")
props := model.MapFromJson(strings.NewReader(data))
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
if hash != model.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
return "", model.NewLocAppError("getTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "")
}
@@ -699,7 +700,7 @@ func GetAuthorizationCode(c *Context, service string, props map[string]string, l
endpoint := sso.AuthEndpoint
scope := sso.Scope
props["hash"] = model.HashPassword(clientId)
props["hash"] = model.HashSha256(clientId)
state := b64.StdEncoding.EncodeToString([]byte(model.MapToJson(props)))
redirectUri := c.GetSiteURL() + "/signup/" + service + "/complete"
@@ -732,7 +733,7 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser
stateProps := model.MapFromJson(strings.NewReader(stateStr))
if !model.ComparePassword(stateProps["hash"], sso.Id) {
if stateProps["hash"] != model.HashSha256(sso.Id) {
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "")
}
+3 -2
View File
@@ -4,10 +4,11 @@
package api
import (
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"net/url"
"testing"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func TestRegisterApp(t *testing.T) {
+1 -1
View File
@@ -1199,7 +1199,7 @@ func verifyEmail(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if model.ComparePassword(hashedId, userId+utils.Cfg.EmailSettings.InviteSalt) {
if hashedId == model.HashSha256(userId+utils.Cfg.EmailSettings.InviteSalt) {
if c.Err = app.VerifyUserEmail(userId); c.Err != nil {
return
} else {
+1 -1
View File
@@ -190,7 +190,7 @@ func TestLogin(t *testing.T) {
props["display_name"] = rteam2.Data.(*model.Team).DisplayName
props["time"] = fmt.Sprintf("%v", model.GetMillis())
data := model.MapToJson(props)
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
hash := model.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
ruser2, err := Client.CreateUserFromSignup(&user2, data, hash)
if err != nil {
+5 -5
View File
@@ -126,7 +126,7 @@ func TestGetAllTeams(t *testing.T) {
rrteams, resp := Client.GetAllTeams("", 1, 1)
CheckNoError(t, resp)
if (len(rrteams) != 1) {
if len(rrteams) != 1 {
t.Fatal("wrong number of teams - should be 1")
}
@@ -139,21 +139,21 @@ func TestGetAllTeams(t *testing.T) {
rrteams1, resp := Client.GetAllTeams("", 1, 0)
CheckNoError(t, resp)
if (len(rrteams1) != 0) {
if len(rrteams1) != 0 {
t.Fatal("wrong number of teams - should be 0")
}
rrteams2, resp := th.SystemAdminClient.GetAllTeams("", 1, 1)
CheckNoError(t, resp)
if (len(rrteams2) != 1) {
if len(rrteams2) != 1 {
t.Fatal("wrong number of teams - should be 1")
}
rrteams2, resp = Client.GetAllTeams("", 1, 0)
CheckNoError(t, resp)
if (len(rrteams2) != 0) {
if len(rrteams2) != 0 {
t.Fatal("wrong number of teams - should be 0")
}
@@ -493,4 +493,4 @@ func TestGetMyTeamsUnread(t *testing.T) {
Client.Logout()
_, resp = Client.GetTeamsUnreadForUser(user.Id, "")
CheckUnauthorizedStatus(t, resp)
}
}
+2 -2
View File
@@ -663,8 +663,8 @@ func verify(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
hashed := model.HashPassword(hashedId)
if model.ComparePassword(hashed, userId+utils.Cfg.EmailSettings.InviteSalt) {
hashed := model.HashSha256(hashedId)
if hashed == model.HashSha256(userId+utils.Cfg.EmailSettings.InviteSalt) {
if c.Err = app.VerifyUserEmail(userId); c.Err != nil {
return
} else {
+11 -12
View File
@@ -18,7 +18,7 @@ func SendChangeUsernameEmail(oldUsername, newUsername, email, locale, siteURL st
subject := T("api.templates.username_change_subject",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"],
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
bodyPage := utils.NewHTMLTemplate("email_change_body", locale)
bodyPage.Props["SiteURL"] = siteURL
@@ -36,12 +36,11 @@ func SendChangeUsernameEmail(oldUsername, newUsername, email, locale, siteURL st
func SendEmailChangeVerifyEmail(userId, newUserEmail, locale, siteURL string) *model.AppError {
T := utils.GetUserTranslations(locale)
link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashPassword(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(newUserEmail))
link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashSha256(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(newUserEmail))
subject := T("api.templates.email_change_verify_subject",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"],
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
bodyPage := utils.NewHTMLTemplate("email_change_verify_body", locale)
bodyPage.Props["SiteURL"] = siteURL
@@ -63,7 +62,7 @@ func SendEmailChangeEmail(oldEmail, newEmail, locale, siteURL string) *model.App
subject := T("api.templates.email_change_subject",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"],
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
bodyPage := utils.NewHTMLTemplate("email_change_body", locale)
bodyPage.Props["SiteURL"] = siteURL
@@ -81,7 +80,7 @@ func SendEmailChangeEmail(oldEmail, newEmail, locale, siteURL string) *model.App
func SendVerifyEmail(userId, userEmail, locale, siteURL string) *model.AppError {
T := utils.GetUserTranslations(locale)
link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashPassword(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(userEmail))
link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashSha256(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(userEmail))
url, _ := url.Parse(siteURL)
@@ -128,7 +127,7 @@ func SendWelcomeEmail(userId string, email string, verified bool, locale, siteUR
subject := T("api.templates.welcome_subject",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"],
"ServerURL": rawUrl.Host})
"ServerURL": rawUrl.Host})
bodyPage := utils.NewHTMLTemplate("welcome_body", locale)
bodyPage.Props["SiteURL"] = siteURL
@@ -145,7 +144,7 @@ func SendWelcomeEmail(userId string, email string, verified bool, locale, siteUR
}
if !verified {
link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashPassword(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(email))
link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashSha256(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(email))
bodyPage.Props["VerifyUrl"] = link
}
@@ -161,7 +160,7 @@ func SendPasswordChangeEmail(email, method, locale, siteURL string) *model.AppEr
subject := T("api.templates.password_change_subject",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"],
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})
bodyPage := utils.NewHTMLTemplate("password_change_body", locale)
bodyPage.Props["SiteURL"] = siteURL
@@ -234,8 +233,8 @@ func SendInviteEmails(team *model.Team, senderName string, invites []string, sit
subject := utils.T("api.templates.invite_subject",
map[string]interface{}{"SenderName": senderName,
"TeamDisplayName": team.DisplayName,
"SiteName": utils.ClientCfg["SiteName"]})
"TeamDisplayName": team.DisplayName,
"SiteName": utils.ClientCfg["SiteName"]})
bodyPage := utils.NewHTMLTemplate("invite_body", model.DEFAULT_LOCALE)
bodyPage.Props["SiteURL"] = siteURL
@@ -253,7 +252,7 @@ func SendInviteEmails(team *model.Team, senderName string, invites []string, sit
props["name"] = team.Name
props["time"] = fmt.Sprintf("%v", model.GetMillis())
data := model.MapToJson(props)
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
hash := model.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", siteURL, url.QueryEscape(data), url.QueryEscape(hash))
if !utils.Cfg.EmailSettings.SendEmailNotifications {
+1 -1
View File
@@ -173,7 +173,7 @@ func AddUserToTeamByTeamId(teamId string, user *model.User, siteURL string) *mod
func AddUserToTeamByHash(userId string, hash string, data string, siteURL string) (*model.Team, *model.AppError) {
props := model.MapFromJson(strings.NewReader(data))
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
if hash != model.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
return nil, model.NewLocAppError("JoinUserToTeamByHash", "api.user.create_user.signup_link_invalid.app_error", nil, "")
}
+1 -1
View File
@@ -36,7 +36,7 @@ func CreateUserWithHash(user *model.User, hash string, data string, siteURL stri
props := model.MapFromJson(strings.NewReader(data))
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
if hash != model.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
return nil, model.NewLocAppError("CreateUserWithHash", "api.user.create_user.signup_link_invalid.app_error", nil, "")
}
+8
View File
@@ -4,6 +4,7 @@
package model
import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
@@ -535,6 +536,13 @@ func UserListFromJson(data io.Reader) []*User {
}
}
func HashSha256(text string) string {
hash := sha256.New()
hash.Write([]byte(text))
return fmt.Sprintf("%x", hash.Sum(nil))
}
// HashPassword generates a hash using the bcrypt.GenerateFromPassword
func HashPassword(password string) string {
hash, err := bcrypt.GenerateFromPassword([]byte(password), 10)