2015-10-08 12:27:09 -04:00
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
2015-06-14 23:53:32 -08:00
// See License.txt for license information.
package api
import (
2015-09-16 09:37:20 -07:00
"fmt"
2015-06-14 23:53:32 -08:00
"net"
"net/http"
"net/url"
"strings"
2015-08-25 11:06:11 -07:00
2016-01-11 09:12:51 -06:00
l4g "github.com/alecthomas/log4go"
2016-04-21 22:37:01 -07:00
"github.com/gorilla/mux"
goi18n "github.com/nicksnyder/go-i18n/i18n"
2015-08-25 11:06:11 -07:00
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
2015-06-14 23:53:32 -08:00
)
var sessionCache * utils . Cache = utils . NewLru ( model . SESSION_CACHE_SIZE )
2016-03-02 21:24:40 -03:00
var allowedMethods [ ] string = [ ] string {
"POST" ,
"GET" ,
"OPTIONS" ,
"PUT" ,
"PATCH" ,
"DELETE" ,
}
2015-06-14 23:53:32 -08:00
type Context struct {
2016-02-08 07:26:10 -05:00
Session model . Session
RequestId string
IpAddress string
Path string
Err * model . AppError
teamURLValid bool
teamURL string
siteURL string
T goi18n . TranslateFunc
Locale string
2016-04-21 22:37:01 -07:00
TeamId string
2015-06-14 23:53:32 -08:00
}
func ApiAppHandler ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , false , false , true , false , false , false }
2015-06-14 23:53:32 -08:00
}
func AppHandler ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , false , false , false , false , false , false }
2015-07-08 11:50:10 -04:00
}
func AppHandlerIndependent ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , false , false , false , false , true , false }
2015-06-14 23:53:32 -08:00
}
func ApiUserRequired ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , true , false , true , true , false , false }
2015-06-14 23:53:32 -08:00
}
func ApiUserRequiredActivity ( h func ( * Context , http . ResponseWriter , * http . Request ) , isUserActivity bool ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , true , false , true , isUserActivity , false , false }
2015-06-14 23:53:32 -08:00
}
func UserRequired ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , true , false , false , false , false , false }
2015-06-14 23:53:32 -08:00
}
func ApiAdminSystemRequired ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
2016-04-04 14:58:05 -04:00
return & handler { h , true , true , true , false , false , false }
}
func ApiAppHandlerTrustRequester ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
return & handler { h , false , false , true , false , false , true }
}
func ApiUserRequiredTrustRequester ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
return & handler { h , true , false , true , true , false , true }
2015-06-14 23:53:32 -08:00
}
2016-05-05 16:35:03 -04:00
func ApiAppHandlerTrustRequesterIndependent ( h func ( * Context , http . ResponseWriter , * http . Request ) ) http . Handler {
return & handler { h , false , false , true , false , true , true }
}
2015-06-14 23:53:32 -08:00
type handler struct {
handleFunc func ( * Context , http . ResponseWriter , * http . Request )
requireUser bool
requireSystemAdmin bool
isApi bool
isUserActivity bool
2015-07-08 11:50:10 -04:00
isTeamIndependent bool
2016-04-04 14:58:05 -04:00
trustRequester bool
2015-06-14 23:53:32 -08:00
}
func ( h handler ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) {
l4g . Debug ( "%v" , r . URL . Path )
c := & Context { }
2016-01-21 14:15:44 -06:00
c . T , c . Locale = utils . GetTranslationsAndLocale ( w , r )
2015-06-14 23:53:32 -08:00
c . RequestId = model . NewId ( )
c . IpAddress = GetIpAddress ( r )
2016-04-21 22:37:01 -07:00
c . TeamId = mux . Vars ( r ) [ "team_id" ]
h . isApi = IsApiCall ( r )
2015-06-14 23:53:32 -08:00
2015-09-16 15:49:12 -04:00
token := ""
isTokenFromQueryString := false
// Attempt to parse token out of the header
authHeader := r . Header . Get ( model . HEADER_AUTH )
if len ( authHeader ) > 6 && strings . ToUpper ( authHeader [ 0 : 6 ] ) == model . HEADER_BEARER {
// Default session token
token = authHeader [ 7 : ]
} else if len ( authHeader ) > 5 && strings . ToLower ( authHeader [ 0 : 5 ] ) == model . HEADER_TOKEN {
// OAuth token
token = authHeader [ 6 : ]
}
// Attempt to parse the token from the cookie
if len ( token ) == 0 {
2016-02-08 07:26:10 -05:00
if cookie , err := r . Cookie ( model . SESSION_COOKIE_TOKEN ) ; err == nil {
token = cookie . Value
2016-04-04 14:58:05 -04:00
if ( h . requireSystemAdmin || h . requireUser ) && ! h . trustRequester {
if r . Header . Get ( model . HEADER_REQUESTED_WITH ) != model . HEADER_REQUESTED_WITH_XML {
2016-04-21 22:37:01 -07:00
c . Err = model . NewLocAppError ( "ServeHTTP" , "api.context.session_expired.app_error" , nil , "token=" + token + " Appears to bea CSRF attempt" )
2016-04-04 14:58:05 -04:00
token = ""
}
}
2015-09-16 15:49:12 -04:00
}
}
// Attempt to parse token out of the query string
if len ( token ) == 0 {
token = r . URL . Query ( ) . Get ( "access_token" )
isTokenFromQueryString = true
}
2015-09-22 12:12:50 -07:00
protocol := GetProtocol ( r )
2016-06-10 13:59:20 +02:00
c . SetSiteURL ( protocol + "://" + r . Host )
2015-06-14 23:53:32 -08:00
w . Header ( ) . Set ( model . HEADER_REQUEST_ID , c . RequestId )
2015-09-17 13:01:40 -07:00
w . Header ( ) . Set ( model . HEADER_VERSION_ID , fmt . Sprintf ( "%v.%v" , model . CurrentVersion , utils . CfgLastModified ) )
2015-07-27 11:59:14 -07:00
// Instruct the browser not to display us in an iframe for anti-clickjacking
if ! h . isApi {
w . Header ( ) . Set ( "X-Frame-Options" , "DENY" )
2016-02-18 12:52:47 -08:00
w . Header ( ) . Set ( "Content-Security-Policy" , "frame-ancestors 'none'" )
2015-09-11 12:11:10 -04:00
} else {
2015-09-16 15:49:12 -04:00
// All api response bodies will be JSON formatted by default
2015-09-11 12:11:10 -04:00
w . Header ( ) . Set ( "Content-Type" , "application/json" )
2016-02-11 13:17:27 -08:00
if r . Method == "GET" {
w . Header ( ) . Set ( "Expires" , "0" )
}
2015-07-27 11:59:14 -07:00
}
2015-06-14 23:53:32 -08:00
2015-09-16 15:49:12 -04:00
if len ( token ) != 0 {
2016-01-20 13:36:16 -06:00
session := GetSession ( token )
2015-06-14 23:53:32 -08:00
if session == nil || session . IsExpired ( ) {
2015-10-01 17:52:47 -07:00
c . RemoveSessionCookie ( w , r )
2016-02-08 07:26:10 -05:00
if h . requireUser || h . requireSystemAdmin {
c . Err = model . NewLocAppError ( "ServeHTTP" , "api.context.session_expired.app_error" , nil , "token=" + token )
c . Err . StatusCode = http . StatusUnauthorized
}
2015-09-16 15:49:12 -04:00
} else if ! session . IsOAuth && isTokenFromQueryString {
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( "ServeHTTP" , "api.context.token_provided.app_error" , nil , "token=" + token )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusUnauthorized
} else {
c . Session = * session
}
}
2015-07-08 11:50:10 -04:00
if h . isApi || h . isTeamIndependent {
c . setTeamURL ( c . GetSiteURL ( ) , false )
c . Path = r . URL . Path
} else {
splitURL := strings . Split ( r . URL . Path , "/" )
c . setTeamURL ( protocol + "://" + r . Host + "/" + splitURL [ 1 ] , true )
c . Path = "/" + strings . Join ( splitURL [ 2 : ] , "/" )
}
2015-06-14 23:53:32 -08:00
if c . Err == nil && h . requireUser {
c . UserRequired ( )
}
if c . Err == nil && h . requireSystemAdmin {
c . SystemAdminRequired ( )
}
2016-05-05 16:35:03 -04:00
if c . Err == nil && len ( c . TeamId ) > 0 && ! h . isTeamIndependent {
2016-04-21 22:37:01 -07:00
c . HasPermissionsToTeam ( c . TeamId , "TeamRoute" )
}
2015-09-16 15:49:12 -04:00
if c . Err == nil && h . isUserActivity && token != "" && len ( c . Session . UserId ) > 0 {
2015-06-14 23:53:32 -08:00
go func ( ) {
2016-01-20 13:36:16 -06:00
if err := ( <- Srv . Store . User ( ) . UpdateUserAndSessionActivity ( c . Session . UserId , c . Session . Id , model . GetMillis ( ) ) ) . Err ; err != nil {
2016-01-21 10:07:29 -03:00
l4g . Error ( utils . T ( "api.context.last_activity_at.error" ) , c . Session . UserId , c . Session . Id , err )
2015-06-14 23:53:32 -08:00
}
} ( )
}
if c . Err == nil {
h . handleFunc ( c , w , r )
}
if c . Err != nil {
2016-01-20 14:36:34 -06:00
c . Err . Translate ( c . T )
2015-06-14 23:53:32 -08:00
c . Err . RequestId = c . RequestId
c . LogError ( c . Err )
c . Err . Where = r . URL . Path
if h . isApi {
w . WriteHeader ( c . Err . StatusCode )
w . Write ( [ ] byte ( c . Err . ToJson ( ) ) )
} else {
if c . Err . StatusCode == http . StatusUnauthorized {
2015-07-08 11:50:10 -04:00
http . Redirect ( w , r , c . GetTeamURL ( ) + "/?redirect=" + url . QueryEscape ( r . URL . Path ) , http . StatusTemporaryRedirect )
2015-06-14 23:53:32 -08:00
} else {
RenderWebError ( c . Err , w , r )
}
}
}
}
2016-03-02 21:24:40 -03:00
func ( cw * CorsWrapper ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) {
2016-03-01 22:12:05 -03:00
if len ( * utils . Cfg . ServiceSettings . AllowCorsFrom ) > 0 {
2016-03-02 21:24:40 -03:00
origin := r . Header . Get ( "Origin" )
if * utils . Cfg . ServiceSettings . AllowCorsFrom == "*" || strings . Contains ( * utils . Cfg . ServiceSettings . AllowCorsFrom , origin ) {
w . Header ( ) . Set ( "Access-Control-Allow-Origin" , origin )
if r . Method == "OPTIONS" {
w . Header ( ) . Set (
"Access-Control-Allow-Methods" ,
strings . Join ( allowedMethods , ", " ) )
w . Header ( ) . Set (
"Access-Control-Allow-Headers" ,
r . Header . Get ( "Access-Control-Request-Headers" ) )
}
}
2016-03-01 22:12:05 -03:00
}
if r . Method == "OPTIONS" {
return
}
cw . router . ServeHTTP ( w , r )
}
2015-09-22 12:12:50 -07:00
func GetProtocol ( r * http . Request ) string {
if r . Header . Get ( model . HEADER_FORWARDED_PROTO ) == "https" {
return "https"
} else {
return "http"
}
}
2015-06-14 23:53:32 -08:00
func ( c * Context ) LogAudit ( extraInfo string ) {
2015-09-16 15:49:12 -04:00
audit := & model . Audit { UserId : c . Session . UserId , IpAddress : c . IpAddress , Action : c . Path , ExtraInfo : extraInfo , SessionId : c . Session . Id }
2016-01-20 13:36:16 -06:00
if r := <- Srv . Store . Audit ( ) . Save ( audit ) ; r . Err != nil {
2015-08-20 15:04:37 -07:00
c . LogError ( r . Err )
}
2015-06-14 23:53:32 -08:00
}
func ( c * Context ) LogAuditWithUserId ( userId , extraInfo string ) {
2015-08-20 15:04:37 -07:00
if len ( c . Session . UserId ) > 0 {
extraInfo = strings . TrimSpace ( extraInfo + " session_user=" + c . Session . UserId )
}
2015-06-14 23:53:32 -08:00
2015-09-16 15:49:12 -04:00
audit := & model . Audit { UserId : userId , IpAddress : c . IpAddress , Action : c . Path , ExtraInfo : extraInfo , SessionId : c . Session . Id }
2016-01-20 13:36:16 -06:00
if r := <- Srv . Store . Audit ( ) . Save ( audit ) ; r . Err != nil {
2015-08-20 15:04:37 -07:00
c . LogError ( r . Err )
}
2015-06-14 23:53:32 -08:00
}
func ( c * Context ) LogError ( err * model . AppError ) {
2016-01-21 10:07:29 -03:00
l4g . Error ( utils . T ( "api.context.log.error" ) , c . Path , err . Where , err . StatusCode ,
2016-04-17 21:32:20 -03:00
c . RequestId , c . Session . UserId , c . IpAddress , err . SystemMessage ( utils . T ) , err . DetailedError )
2015-06-14 23:53:32 -08:00
}
2016-06-29 04:16:20 -08:00
func ( c * Context ) LogDebug ( err * model . AppError ) {
l4g . Debug ( utils . T ( "api.context.log.error" ) , c . Path , err . Where , err . StatusCode ,
c . RequestId , c . Session . UserId , c . IpAddress , err . SystemMessage ( utils . T ) , err . DetailedError )
}
2015-06-14 23:53:32 -08:00
func ( c * Context ) UserRequired ( ) {
if len ( c . Session . UserId ) == 0 {
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( "" , "api.context.session_expired.app_error" , nil , "UserRequired" )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusUnauthorized
return
}
}
func ( c * Context ) SystemAdminRequired ( ) {
if len ( c . Session . UserId ) == 0 {
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( "" , "api.context.session_expired.app_error" , nil , "SystemAdminRequired" )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusUnauthorized
return
} else if ! c . IsSystemAdmin ( ) {
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( "" , "api.context.permissions.app_error" , nil , "AdminRequired" )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusForbidden
return
}
}
func ( c * Context ) HasPermissionsToUser ( userId string , where string ) bool {
// You are the user
if c . Session . UserId == userId {
return true
}
// You're a mattermost system admin and you're on the VPN
if c . IsSystemAdmin ( ) {
return true
}
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( where , "api.context.permissions.app_error" , nil , "userId=" + userId )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusForbidden
return false
}
func ( c * Context ) HasPermissionsToTeam ( teamId string , where string ) bool {
2016-04-21 22:37:01 -07:00
if c . IsSystemAdmin ( ) {
2015-06-14 23:53:32 -08:00
return true
}
2016-04-21 22:37:01 -07:00
for _ , teamMember := range c . Session . TeamMembers {
if teamId == teamMember . TeamId {
return true
}
2015-06-14 23:53:32 -08:00
}
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( where , "api.context.permissions.app_error" , nil , "userId=" + c . Session . UserId + ", teamId=" + teamId )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusForbidden
return false
}
func ( c * Context ) HasPermissionsToChannel ( sc store . StoreChannel , where string ) bool {
if cresult := <- sc ; cresult . Err != nil {
c . Err = cresult . Err
return false
} else if cresult . Data . ( int64 ) != 1 {
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( where , "api.context.permissions.app_error" , nil , "userId=" + c . Session . UserId )
2015-06-14 23:53:32 -08:00
c . Err . StatusCode = http . StatusForbidden
return false
}
return true
}
2015-09-10 18:32:22 -07:00
func ( c * Context ) HasSystemAdminPermissions ( where string ) bool {
if c . IsSystemAdmin ( ) {
return true
}
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( where , "api.context.system_permissions.app_error" , nil , "userId=" + c . Session . UserId )
2015-09-10 18:32:22 -07:00
c . Err . StatusCode = http . StatusForbidden
return false
}
2015-09-30 09:34:05 -04:00
func ( c * Context ) IsSystemAdmin ( ) bool {
if model . IsInRole ( c . Session . Roles , model . ROLE_SYSTEM_ADMIN ) {
return true
}
return false
}
2015-09-30 11:30:11 -04:00
func ( c * Context ) IsTeamAdmin ( ) bool {
2016-04-21 22:37:01 -07:00
if c . IsSystemAdmin ( ) {
2015-09-30 09:34:05 -04:00
return true
2015-07-16 13:40:18 -07:00
}
2016-04-21 22:37:01 -07:00
2016-05-06 11:28:22 -07:00
teamMember := c . Session . GetTeamByTeamId ( c . TeamId )
if teamMember == nil {
2016-04-21 22:37:01 -07:00
return false
}
2016-05-06 11:28:22 -07:00
return teamMember . IsTeamAdmin ( )
2015-07-16 13:40:18 -07:00
}
2015-10-01 17:52:47 -07:00
func ( c * Context ) RemoveSessionCookie ( w http . ResponseWriter , r * http . Request ) {
2015-10-20 14:49:42 -07:00
cookie := & http . Cookie {
2015-10-20 04:37:51 -07:00
Name : model . SESSION_COOKIE_TOKEN ,
2015-10-20 14:49:42 -07:00
Value : "" ,
2015-10-01 17:52:47 -07:00
Path : "/" ,
2015-10-20 14:49:42 -07:00
MaxAge : - 1 ,
2015-10-01 17:52:47 -07:00
HttpOnly : true ,
}
2015-10-20 14:49:42 -07:00
http . SetCookie ( w , cookie )
2015-06-14 23:53:32 -08:00
}
func ( c * Context ) SetInvalidParam ( where string , name string ) {
2016-05-05 16:35:03 -04:00
c . Err = NewInvalidParamError ( where , name )
}
func NewInvalidParamError ( where string , name string ) * model . AppError {
err := model . NewLocAppError ( where , "api.context.invalid_param.app_error" , map [ string ] interface { } { "Name" : name } , "" )
err . StatusCode = http . StatusBadRequest
return err
2015-06-14 23:53:32 -08:00
}
func ( c * Context ) SetUnknownError ( where string , details string ) {
2016-01-21 10:07:29 -03:00
c . Err = model . NewLocAppError ( where , "api.context.unknown.app_error" , nil , details )
2015-06-14 23:53:32 -08:00
}
2015-07-08 11:50:10 -04:00
func ( c * Context ) setTeamURL ( url string , valid bool ) {
c . teamURL = url
c . teamURLValid = valid
}
2015-10-01 17:52:47 -07:00
func ( c * Context ) SetTeamURLFromSession ( ) {
2016-04-21 22:37:01 -07:00
if result := <- Srv . Store . Team ( ) . Get ( c . TeamId ) ; result . Err == nil {
2015-07-08 11:50:10 -04:00
c . setTeamURL ( c . GetSiteURL ( ) + "/" + result . Data . ( * model . Team ) . Name , true )
}
}
2016-06-10 13:59:20 +02:00
func ( c * Context ) SetSiteURL ( url string ) {
2015-07-08 11:50:10 -04:00
c . siteURL = url
}
func ( c * Context ) GetTeamURLFromTeam ( team * model . Team ) string {
return c . GetSiteURL ( ) + "/" + team . Name
}
func ( c * Context ) GetTeamURL ( ) string {
if ! c . teamURLValid {
2015-10-01 17:52:47 -07:00
c . SetTeamURLFromSession ( )
2015-07-08 11:50:10 -04:00
if ! c . teamURLValid {
2016-01-21 10:07:29 -03:00
l4g . Debug ( utils . T ( "api.context.invalid_team_url.debug" ) )
2015-07-08 11:50:10 -04:00
}
}
return c . teamURL
}
func ( c * Context ) GetSiteURL ( ) string {
return c . siteURL
}
2016-04-21 22:37:01 -07:00
func IsApiCall ( r * http . Request ) bool {
return strings . Index ( r . URL . Path , "/api/" ) == 0
}
2015-06-14 23:53:32 -08:00
func GetIpAddress ( r * http . Request ) string {
address := r . Header . Get ( model . HEADER_FORWARDED )
2015-09-22 12:12:50 -07:00
if len ( address ) == 0 {
address = r . Header . Get ( model . HEADER_REAL_IP )
}
2015-06-14 23:53:32 -08:00
if len ( address ) == 0 {
address , _ , _ = net . SplitHostPort ( r . RemoteAddr )
}
return address
}
func RenderWebError ( err * model . AppError , w http . ResponseWriter , r * http . Request ) {
2016-04-01 11:48:19 -04:00
T , _ := utils . GetTranslationsAndLocale ( w , r )
title := T ( "api.templates.error.title" , map [ string ] interface { } { "SiteName" : utils . ClientCfg [ "SiteName" ] } )
message := err . Message
details := err . DetailedError
link := "/"
linkMessage := T ( "api.templates.error.link" )
http . Redirect (
w ,
r ,
"/error?title=" + url . QueryEscape ( title ) +
"&message=" + url . QueryEscape ( message ) +
"&details=" + url . QueryEscape ( details ) +
"&link=" + url . QueryEscape ( link ) +
"&linkmessage=" + url . QueryEscape ( linkMessage ) ,
http . StatusTemporaryRedirect )
2015-06-14 23:53:32 -08:00
}
func Handle404 ( w http . ResponseWriter , r * http . Request ) {
2016-01-21 10:07:29 -03:00
err := model . NewLocAppError ( "Handle404" , "api.context.404.app_error" , nil , "" )
2016-04-21 22:37:01 -07:00
err . Translate ( utils . T )
2015-06-14 23:53:32 -08:00
err . StatusCode = http . StatusNotFound
2016-06-29 04:16:20 -08:00
// filter out old paths that are poluting the log file
if strings . Contains ( r . URL . Path , "/api/v1/" ) {
l4g . Debug ( "%v: code=404 ip=%v" , r . URL . Path , GetIpAddress ( r ) )
} else {
l4g . Error ( "%v: code=404 ip=%v" , r . URL . Path , GetIpAddress ( r ) )
}
2016-04-21 22:37:01 -07:00
if IsApiCall ( r ) {
w . WriteHeader ( err . StatusCode )
err . DetailedError = "There doesn't appear to be an api call for the url='" + r . URL . Path + "'. Typo? are you missing a team_id or user_id as part of the url?"
w . Write ( [ ] byte ( err . ToJson ( ) ) )
} else {
RenderWebError ( err , w , r )
}
2015-06-14 23:53:32 -08:00
}
2015-09-16 15:49:12 -04:00
2016-01-20 13:36:16 -06:00
func GetSession ( token string ) * model . Session {
2015-10-16 19:05:55 -07:00
var session * model . Session
if ts , ok := sessionCache . Get ( token ) ; ok {
session = ts . ( * model . Session )
}
if session == nil {
2016-01-20 13:36:16 -06:00
if sessionResult := <- Srv . Store . Session ( ) . Get ( token ) ; sessionResult . Err != nil {
2016-01-21 10:07:29 -03:00
l4g . Error ( utils . T ( "api.context.invalid_token.error" ) , token , sessionResult . Err . DetailedError )
2015-10-16 19:05:55 -07:00
} else {
session = sessionResult . Data . ( * model . Session )
2016-01-05 11:13:25 -06:00
2016-05-17 13:55:51 -07:00
if session . IsExpired ( ) || session . Token != token {
2016-01-05 11:13:25 -06:00
return nil
} else {
AddSessionToCache ( session )
return session
}
2015-10-16 19:05:55 -07:00
}
}
return session
}
2016-04-21 22:37:01 -07:00
func RemoveAllSessionsForUserId ( userId string ) {
keys := sessionCache . Keys ( )
for _ , key := range keys {
if ts , ok := sessionCache . Get ( key ) ; ok {
session := ts . ( * model . Session )
if session . UserId == userId {
sessionCache . Remove ( key )
}
}
}
}
2015-09-16 15:49:12 -04:00
func AddSessionToCache ( session * model . Session ) {
2016-01-05 11:13:25 -06:00
sessionCache . AddWithExpiresInSecs ( session . Token , session , int64 ( * utils . Cfg . ServiceSettings . SessionCacheInMinutes * 60 ) )
2015-09-16 15:49:12 -04:00
}