1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package model
5
6import (
7	"strconv"
8	"strings"
9
10	"github.com/mattermost/mattermost-server/v6/shared/mlog"
11)
12
13const (
14	SessionCookieToken            = "MMAUTHTOKEN"
15	SessionCookieUser             = "MMUSERID"
16	SessionCookieCsrf             = "MMCSRF"
17	SessionCacheSize              = 35000
18	SessionPropPlatform           = "platform"
19	SessionPropOs                 = "os"
20	SessionPropBrowser            = "browser"
21	SessionPropType               = "type"
22	SessionPropUserAccessTokenId  = "user_access_token_id"
23	SessionPropIsBot              = "is_bot"
24	SessionPropIsBotValue         = "true"
25	SessionTypeUserAccessToken    = "UserAccessToken"
26	SessionTypeCloudKey           = "CloudKey"
27	SessionTypeRemoteclusterToken = "RemoteClusterToken"
28	SessionPropIsGuest            = "is_guest"
29	SessionActivityTimeout        = 1000 * 60 * 5 // 5 minutes
30	SessionUserAccessTokenExpiry  = 100 * 365     // 100 years
31)
32
33//msgp StringMap
34type StringMap map[string]string
35
36//msgp:tuple Session
37
38// Session contains the user session details.
39// This struct's serializer methods are auto-generated. If a new field is added/removed,
40// please run make gen-serialized.
41type Session struct {
42	Id             string        `json:"id"`
43	Token          string        `json:"token"`
44	CreateAt       int64         `json:"create_at"`
45	ExpiresAt      int64         `json:"expires_at"`
46	LastActivityAt int64         `json:"last_activity_at"`
47	UserId         string        `json:"user_id"`
48	DeviceId       string        `json:"device_id"`
49	Roles          string        `json:"roles"`
50	IsOAuth        bool          `json:"is_oauth"`
51	ExpiredNotify  bool          `json:"expired_notify"`
52	Props          StringMap     `json:"props"`
53	TeamMembers    []*TeamMember `json:"team_members" db:"-"`
54	Local          bool          `json:"local" db:"-"`
55}
56
57// Returns true if the session is unrestricted, which should grant it
58// with all permissions. This is used for local mode sessions
59func (s *Session) IsUnrestricted() bool {
60	return s.Local
61}
62
63func (s *Session) DeepCopy() *Session {
64	copySession := *s
65
66	if s.Props != nil {
67		copySession.Props = CopyStringMap(s.Props)
68	}
69
70	if s.TeamMembers != nil {
71		copySession.TeamMembers = make([]*TeamMember, len(s.TeamMembers))
72		for index, tm := range s.TeamMembers {
73			copySession.TeamMembers[index] = new(TeamMember)
74			*copySession.TeamMembers[index] = *tm
75		}
76	}
77
78	return &copySession
79}
80
81func (s *Session) PreSave() {
82	if s.Id == "" {
83		s.Id = NewId()
84	}
85
86	if s.Token == "" {
87		s.Token = NewId()
88	}
89
90	s.CreateAt = GetMillis()
91	s.LastActivityAt = s.CreateAt
92
93	if s.Props == nil {
94		s.Props = make(map[string]string)
95	}
96}
97
98func (s *Session) Sanitize() {
99	s.Token = ""
100}
101
102func (s *Session) IsExpired() bool {
103
104	if s.ExpiresAt <= 0 {
105		return false
106	}
107
108	if GetMillis() > s.ExpiresAt {
109		return true
110	}
111
112	return false
113}
114
115func (s *Session) AddProp(key string, value string) {
116
117	if s.Props == nil {
118		s.Props = make(map[string]string)
119	}
120
121	s.Props[key] = value
122}
123
124func (s *Session) GetTeamByTeamId(teamId string) *TeamMember {
125	for _, team := range s.TeamMembers {
126		if team.TeamId == teamId {
127			return team
128		}
129	}
130
131	return nil
132}
133
134func (s *Session) IsMobileApp() bool {
135	return s.DeviceId != "" || s.IsMobile()
136}
137
138func (s *Session) IsMobile() bool {
139	val, ok := s.Props[UserAuthServiceIsMobile]
140	if !ok {
141		return false
142	}
143	isMobile, err := strconv.ParseBool(val)
144	if err != nil {
145		mlog.Debug("Error parsing boolean property from Session", mlog.Err(err))
146		return false
147	}
148	return isMobile
149}
150
151func (s *Session) IsSaml() bool {
152	val, ok := s.Props[UserAuthServiceIsSaml]
153	if !ok {
154		return false
155	}
156	isSaml, err := strconv.ParseBool(val)
157	if err != nil {
158		mlog.Debug("Error parsing boolean property from Session", mlog.Err(err))
159		return false
160	}
161	return isSaml
162}
163
164func (s *Session) IsOAuthUser() bool {
165	val, ok := s.Props[UserAuthServiceIsOAuth]
166	if !ok {
167		return false
168	}
169	isOAuthUser, err := strconv.ParseBool(val)
170	if err != nil {
171		mlog.Debug("Error parsing boolean property from Session", mlog.Err(err))
172		return false
173	}
174	return isOAuthUser
175}
176
177func (s *Session) IsSSOLogin() bool {
178	return s.IsOAuthUser() || s.IsSaml()
179}
180
181func (s *Session) GetUserRoles() []string {
182	return strings.Fields(s.Roles)
183}
184
185func (s *Session) GenerateCSRF() string {
186	token := NewId()
187	s.AddProp("csrf", token)
188	return token
189}
190
191func (s *Session) GetCSRF() string {
192	if s.Props == nil {
193		return ""
194	}
195
196	return s.Props["csrf"]
197}
198