github.com/dschalla/mattermost-server@v4.8.1-rc1+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  	domain := a.GetCookieDomain()
   117  	expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0)
   118  	sessionCookie := &http.Cookie{
   119  		Name:     model.SESSION_COOKIE_TOKEN,
   120  		Value:    session.Token,
   121  		Path:     "/",
   122  		MaxAge:   maxAge,
   123  		Expires:  expiresAt,
   124  		HttpOnly: true,
   125  		Domain:   domain,
   126  		Secure:   secure,
   127  	}
   128  
   129  	userCookie := &http.Cookie{
   130  		Name:    model.SESSION_COOKIE_USER,
   131  		Value:   user.Id,
   132  		Path:    "/",
   133  		MaxAge:  maxAge,
   134  		Expires: expiresAt,
   135  		Domain:  domain,
   136  		Secure:  secure,
   137  	}
   138  
   139  	http.SetCookie(w, sessionCookie)
   140  	http.SetCookie(w, userCookie)
   141  
   142  	return session, nil
   143  }
   144  
   145  func GetProtocol(r *http.Request) string {
   146  	if r.Header.Get(model.HEADER_FORWARDED_PROTO) == "https" || r.TLS != nil {
   147  		return "https"
   148  	} else {
   149  		return "http"
   150  	}
   151  }