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  }