summaryrefslogtreecommitdiffstats
path: root/app/session.go
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2017-07-31 12:59:32 -0400
committerGitHub <noreply@github.com>2017-07-31 12:59:32 -0400
commit59992ae4a4638006ec1489dd834151b258c1728c (patch)
tree8bc5c0fa8f6a4d6a40026c965bd865c1110af838 /app/session.go
parented62660e96528920b0ecb8c755265c6c8d2756c4 (diff)
downloadchat-59992ae4a4638006ec1489dd834151b258c1728c.tar.gz
chat-59992ae4a4638006ec1489dd834151b258c1728c.tar.bz2
chat-59992ae4a4638006ec1489dd834151b258c1728c.zip
PLT-6763 Implement user access tokens and new roles (server-side) (#6972)
* Implement user access tokens and new roles * Update config.json * Add public post permission to apiv3 * Remove old comment * Fix model unit test * Updates to store per feedback * Updates per feedback from CS
Diffstat (limited to 'app/session.go')
-rw-r--r--app/session.go130
1 files changed, 121 insertions, 9 deletions
diff --git a/app/session.go b/app/session.go
index 4b1ea18f2..07f5c6e0a 100644
--- a/app/session.go
+++ b/app/session.go
@@ -16,6 +16,8 @@ import (
var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE)
func CreateSession(session *model.Session) (*model.Session, *model.AppError) {
+ session.Token = ""
+
if result := <-Srv.Store.Session().Save(session); result.Err != nil {
return nil, result.Err
} else {
@@ -43,22 +45,31 @@ func GetSession(token string) (*model.Session, *model.AppError) {
}
if session == nil {
- if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil {
- return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": sessionResult.Err.DetailedError}, "")
- } else {
+ if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err == nil {
session = sessionResult.Data.(*model.Session)
- if session == nil || session.IsExpired() || session.Token != token {
- return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": ""}, "")
- } else {
- AddSessionToCache(session)
- return session, nil
+ if session != nil {
+ if session.Token != token {
+ return nil, model.NewAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": ""}, "", http.StatusUnauthorized)
+ }
+
+ if !session.IsExpired() {
+ AddSessionToCache(session)
+ }
}
}
}
+ if session == nil {
+ var err *model.AppError
+ session, err = createSessionForUserAccessToken(token)
+ if err != nil {
+ return nil, model.NewAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token}, err.Error(), http.StatusUnauthorized)
+ }
+ }
+
if session == nil || session.IsExpired() {
- return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token}, "")
+ return nil, model.NewAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token}, "", http.StatusUnauthorized)
}
return session, nil
@@ -200,3 +211,104 @@ func UpdateLastActivityAtIfNeeded(session model.Session) {
session.LastActivityAt = now
AddSessionToCache(&session)
}
+
+func CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) {
+ if !*utils.Cfg.ServiceSettings.EnableUserAccessTokens {
+ return nil, model.NewAppError("CreateUserAccessToken", "app.user_access_token.disabled", nil, "", http.StatusNotImplemented)
+ }
+
+ token.Token = model.NewId()
+
+ if result := <-Srv.Store.UserAccessToken().Save(token); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.UserAccessToken), nil
+ }
+}
+
+func createSessionForUserAccessToken(tokenString string) (*model.Session, *model.AppError) {
+ if !*utils.Cfg.ServiceSettings.EnableUserAccessTokens {
+ return nil, model.NewAppError("createSessionForUserAccessToken", "app.user_access_token.invalid_or_missing", nil, "EnableUserAccessTokens=false", http.StatusUnauthorized)
+ }
+
+ var token *model.UserAccessToken
+ if result := <-Srv.Store.UserAccessToken().GetByToken(tokenString); result.Err != nil {
+ return nil, model.NewAppError("createSessionForUserAccessToken", "app.user_access_token.invalid_or_missing", nil, result.Err.Error(), http.StatusUnauthorized)
+ } else {
+ token = result.Data.(*model.UserAccessToken)
+ }
+
+ var user *model.User
+ if result := <-Srv.Store.User().Get(token.UserId); result.Err != nil {
+ return nil, result.Err
+ } else {
+ user = result.Data.(*model.User)
+ }
+
+ if user.DeleteAt != 0 {
+ return nil, model.NewAppError("createSessionForUserAccessToken", "app.user_access_token.invalid_or_missing", nil, "inactive_user_id="+user.Id, http.StatusUnauthorized)
+ }
+
+ session := &model.Session{
+ Token: token.Token,
+ UserId: user.Id,
+ Roles: user.GetRawRoles(),
+ IsOAuth: false,
+ }
+
+ session.AddProp(model.SESSION_PROP_USER_ACCESS_TOKEN_ID, token.Id)
+ session.AddProp(model.SESSION_PROP_TYPE, model.SESSION_TYPE_USER_ACCESS_TOKEN)
+ session.SetExpireInDays(model.SESSION_USER_ACCESS_TOKEN_EXPIRY)
+
+ if result := <-Srv.Store.Session().Save(session); result.Err != nil {
+ return nil, result.Err
+ } else {
+ session := result.Data.(*model.Session)
+
+ AddSessionToCache(session)
+
+ return session, nil
+ }
+}
+
+func RevokeUserAccessToken(token *model.UserAccessToken) *model.AppError {
+ var session *model.Session
+ if result := <-Srv.Store.Session().Get(token.Token); result.Err == nil {
+ session = result.Data.(*model.Session)
+ }
+
+ if result := <-Srv.Store.UserAccessToken().Delete(token.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if session == nil {
+ return nil
+ }
+
+ return RevokeSession(session)
+}
+
+func GetUserAccessTokensForUser(userId string, page, perPage int) ([]*model.UserAccessToken, *model.AppError) {
+ if result := <-Srv.Store.UserAccessToken().GetByUser(userId, page*perPage, perPage); result.Err != nil {
+ return nil, result.Err
+ } else {
+ tokens := result.Data.([]*model.UserAccessToken)
+ for _, token := range tokens {
+ token.Token = ""
+ }
+
+ return tokens, nil
+ }
+}
+
+func GetUserAccessToken(tokenId string, sanitize bool) (*model.UserAccessToken, *model.AppError) {
+ if result := <-Srv.Store.UserAccessToken().Get(tokenId); result.Err != nil {
+ return nil, result.Err
+ } else {
+ token := result.Data.(*model.UserAccessToken)
+ if sanitize {
+ token.Token = ""
+ }
+ return token, nil
+ }
+}