github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+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 "strings" 10 "time" 11 12 "github.com/mattermost/mattermost-server/model" 13 "github.com/mssola/user_agent" 14 ) 15 16 func (a *App) AuthenticateUserForLogin(id, loginId, password, mfaToken, deviceId string, ldapOnly bool) (*model.User, *model.AppError) { 17 if len(password) == 0 { 18 err := model.NewAppError("AuthenticateUserForLogin", "api.user.login.blank_pwd.app_error", nil, "", http.StatusBadRequest) 19 return nil, err 20 } 21 22 var user *model.User 23 var err *model.AppError 24 25 if len(id) != 0 { 26 if user, err = a.GetUser(id); err != nil { 27 err.StatusCode = http.StatusBadRequest 28 if a.Metrics != nil { 29 a.Metrics.IncrementLoginFail() 30 } 31 return nil, err 32 } 33 } else { 34 if user, err = a.GetUserForLogin(loginId, ldapOnly); err != nil { 35 if a.Metrics != nil { 36 a.Metrics.IncrementLoginFail() 37 } 38 return nil, err 39 } 40 } 41 42 // and then authenticate them 43 if user, err = a.authenticateUser(user, password, mfaToken); err != nil { 44 if a.Metrics != nil { 45 a.Metrics.IncrementLoginFail() 46 } 47 return nil, err 48 } 49 50 if a.Metrics != nil { 51 a.Metrics.IncrementLogin() 52 } 53 54 return user, nil 55 } 56 57 func (a *App) DoLogin(w http.ResponseWriter, r *http.Request, user *model.User, deviceId string) (*model.Session, *model.AppError) { 58 session := &model.Session{UserId: user.Id, Roles: user.GetRawRoles(), DeviceId: deviceId, IsOAuth: false} 59 60 maxAge := *a.Config().ServiceSettings.SessionLengthWebInDays * 60 * 60 * 24 61 62 if len(deviceId) > 0 { 63 session.SetExpireInDays(*a.Config().ServiceSettings.SessionLengthMobileInDays) 64 65 // A special case where we logout of all other sessions with the same Id 66 if err := a.RevokeSessionsForDeviceId(user.Id, deviceId, ""); err != nil { 67 err.StatusCode = http.StatusInternalServerError 68 return nil, err 69 } 70 } else { 71 session.SetExpireInDays(*a.Config().ServiceSettings.SessionLengthWebInDays) 72 } 73 74 ua := user_agent.New(r.UserAgent()) 75 76 plat := ua.Platform() 77 if plat == "" { 78 plat = "unknown" 79 } 80 81 os := ua.OS() 82 if os == "" { 83 os = "unknown" 84 } 85 86 bname, bversion := ua.Browser() 87 if bname == "" { 88 bname = "unknown" 89 } 90 91 if strings.Contains(r.UserAgent(), "Mattermost") { 92 bname = "Desktop App" 93 } 94 95 if bversion == "" { 96 bversion = "0.0" 97 } 98 99 session.AddProp(model.SESSION_PROP_PLATFORM, plat) 100 session.AddProp(model.SESSION_PROP_OS, os) 101 session.AddProp(model.SESSION_PROP_BROWSER, fmt.Sprintf("%v/%v", bname, bversion)) 102 103 var err *model.AppError 104 if session, err = a.CreateSession(session); err != nil { 105 err.StatusCode = http.StatusInternalServerError 106 return nil, err 107 } 108 109 w.Header().Set(model.HEADER_TOKEN, session.Token) 110 111 secure := false 112 if GetProtocol(r) == "https" { 113 secure = true 114 } 115 116 expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0) 117 sessionCookie := &http.Cookie{ 118 Name: model.SESSION_COOKIE_TOKEN, 119 Value: session.Token, 120 Path: "/", 121 MaxAge: maxAge, 122 Expires: expiresAt, 123 HttpOnly: true, 124 Secure: secure, 125 } 126 127 userCookie := &http.Cookie{ 128 Name: model.SESSION_COOKIE_USER, 129 Value: user.Id, 130 Path: "/", 131 MaxAge: maxAge, 132 Expires: expiresAt, 133 Secure: secure, 134 } 135 136 http.SetCookie(w, sessionCookie) 137 http.SetCookie(w, userCookie) 138 139 return session, nil 140 } 141 142 func GetProtocol(r *http.Request) string { 143 if r.Header.Get(model.HEADER_FORWARDED_PROTO) == "https" || r.TLS != nil { 144 return "https" 145 } else { 146 return "http" 147 } 148 }