github.com/keys-pub/mattermost-server@v4.10.10+incompatible/app/login.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/http" 9 "time" 10 11 "github.com/avct/uasurfer" 12 "github.com/mattermost/mattermost-server/model" 13 ) 14 15 func (a *App) AuthenticateUserForLogin(id, loginId, password, mfaToken, deviceId string, ldapOnly bool) (*model.User, *model.AppError) { 16 if len(password) == 0 { 17 err := model.NewAppError("AuthenticateUserForLogin", "api.user.login.blank_pwd.app_error", nil, "", http.StatusBadRequest) 18 return nil, err 19 } 20 21 var user *model.User 22 var err *model.AppError 23 24 if len(id) != 0 { 25 if user, err = a.GetUser(id); err != nil { 26 err.StatusCode = http.StatusBadRequest 27 if a.Metrics != nil { 28 a.Metrics.IncrementLoginFail() 29 } 30 return nil, err 31 } 32 } else { 33 if user, err = a.GetUserForLogin(loginId, ldapOnly); err != nil { 34 if a.Metrics != nil { 35 a.Metrics.IncrementLoginFail() 36 } 37 return nil, err 38 } 39 } 40 41 // and then authenticate them 42 if user, err = a.authenticateUser(user, password, mfaToken); err != nil { 43 if a.Metrics != nil { 44 a.Metrics.IncrementLoginFail() 45 } 46 return nil, err 47 } 48 49 if a.Metrics != nil { 50 a.Metrics.IncrementLogin() 51 } 52 53 return user, nil 54 } 55 56 func (a *App) DoLogin(w http.ResponseWriter, r *http.Request, user *model.User, deviceId string) (*model.Session, *model.AppError) { 57 session := &model.Session{UserId: user.Id, Roles: user.GetRawRoles(), DeviceId: deviceId, IsOAuth: false} 58 59 if len(deviceId) > 0 { 60 session.SetExpireInDays(*a.Config().ServiceSettings.SessionLengthMobileInDays) 61 62 // A special case where we logout of all other sessions with the same Id 63 if err := a.RevokeSessionsForDeviceId(user.Id, deviceId, ""); err != nil { 64 err.StatusCode = http.StatusInternalServerError 65 return nil, err 66 } 67 } else { 68 session.SetExpireInDays(*a.Config().ServiceSettings.SessionLengthWebInDays) 69 } 70 71 ua := uasurfer.Parse(r.UserAgent()) 72 73 plat := getPlatformName(ua) 74 os := getOSName(ua) 75 bname := getBrowserName(ua, r.UserAgent()) 76 bversion := getBrowserVersion(ua, r.UserAgent()) 77 78 session.AddProp(model.SESSION_PROP_PLATFORM, plat) 79 session.AddProp(model.SESSION_PROP_OS, os) 80 session.AddProp(model.SESSION_PROP_BROWSER, fmt.Sprintf("%v/%v", bname, bversion)) 81 82 var err *model.AppError 83 if session, err = a.CreateSession(session); err != nil { 84 err.StatusCode = http.StatusInternalServerError 85 return nil, err 86 } 87 88 w.Header().Set(model.HEADER_TOKEN, session.Token) 89 90 return session, nil 91 } 92 93 func (a *App) AttachSessionCookies(w http.ResponseWriter, r *http.Request, session *model.Session) { 94 secure := false 95 if GetProtocol(r) == "https" { 96 secure = true 97 } 98 99 maxAge := *a.Config().ServiceSettings.SessionLengthWebInDays * 60 * 60 * 24 100 domain := a.GetCookieDomain() 101 expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0) 102 sessionCookie := &http.Cookie{ 103 Name: model.SESSION_COOKIE_TOKEN, 104 Value: session.Token, 105 Path: "/", 106 MaxAge: maxAge, 107 Expires: expiresAt, 108 HttpOnly: true, 109 Domain: domain, 110 Secure: secure, 111 } 112 113 userCookie := &http.Cookie{ 114 Name: model.SESSION_COOKIE_USER, 115 Value: session.UserId, 116 Path: "/", 117 MaxAge: maxAge, 118 Expires: expiresAt, 119 Domain: domain, 120 Secure: secure, 121 } 122 123 http.SetCookie(w, sessionCookie) 124 http.SetCookie(w, userCookie) 125 } 126 127 func GetProtocol(r *http.Request) string { 128 if r.Header.Get(model.HEADER_FORWARDED_PROTO) == "https" || r.TLS != nil { 129 return "https" 130 } else { 131 return "http" 132 } 133 }