From 47e6a33a4505e13ba4edf37ff1f8fbdadb279ee3 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Wed, 16 Sep 2015 15:49:12 -0400 Subject: Implement OAuth2 service provider functionality. --- store/sql_oauth_store.go | 334 ++++++++++++++++++++++++++++++++++++++++ store/sql_oauth_store_test.go | 182 ++++++++++++++++++++++ store/sql_session_store.go | 25 +-- store/sql_session_store_test.go | 4 +- store/sql_store.go | 27 +++- store/store.go | 19 ++- 6 files changed, 568 insertions(+), 23 deletions(-) create mode 100644 store/sql_oauth_store.go create mode 100644 store/sql_oauth_store_test.go (limited to 'store') diff --git a/store/sql_oauth_store.go b/store/sql_oauth_store.go new file mode 100644 index 000000000..2a6fa3118 --- /dev/null +++ b/store/sql_oauth_store.go @@ -0,0 +1,334 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +package store + +import ( + "github.com/mattermost/platform/model" + "strings" +) + +type SqlOAuthStore struct { + *SqlStore +} + +func NewSqlOAuthStore(sqlStore *SqlStore) OAuthStore { + as := &SqlOAuthStore{sqlStore} + + for _, db := range sqlStore.GetAllConns() { + table := db.AddTableWithName(model.OAuthApp{}, "OAuthApps").SetKeys(false, "Id") + table.ColMap("Id").SetMaxSize(26) + table.ColMap("CreatorId").SetMaxSize(26) + table.ColMap("ClientSecret").SetMaxSize(128) + table.ColMap("Name").SetMaxSize(64) + table.ColMap("Description").SetMaxSize(512) + table.ColMap("CallbackUrls").SetMaxSize(1024) + table.ColMap("Homepage").SetMaxSize(256) + + tableAuth := db.AddTableWithName(model.AuthData{}, "OAuthAuthData").SetKeys(false, "Code") + tableAuth.ColMap("UserId").SetMaxSize(26) + tableAuth.ColMap("ClientId").SetMaxSize(26) + tableAuth.ColMap("Code").SetMaxSize(128) + tableAuth.ColMap("RedirectUri").SetMaxSize(256) + tableAuth.ColMap("State").SetMaxSize(128) + tableAuth.ColMap("Scope").SetMaxSize(128) + + tableAccess := db.AddTableWithName(model.AccessData{}, "OAuthAccessData").SetKeys(false, "Token") + tableAccess.ColMap("AuthCode").SetMaxSize(128) + tableAccess.ColMap("Token").SetMaxSize(26) + tableAccess.ColMap("RefreshToken").SetMaxSize(26) + tableAccess.ColMap("RedirectUri").SetMaxSize(256) + } + + return as +} + +func (as SqlOAuthStore) UpgradeSchemaIfNeeded() { +} + +func (as SqlOAuthStore) CreateIndexesIfNotExists() { + as.CreateIndexIfNotExists("idx_oauthapps_creator_id", "OAuthApps", "CreatorId") + as.CreateIndexIfNotExists("idx_oauthaccessdata_auth_code", "OAuthAccessData", "AuthCode") + as.CreateIndexIfNotExists("idx_oauthauthdata_client_id", "OAuthAuthData", "Code") +} + +func (as SqlOAuthStore) SaveApp(app *model.OAuthApp) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + if len(app.Id) > 0 { + result.Err = model.NewAppError("SqlOAuthStore.SaveApp", "Must call update for exisiting app", "app_id="+app.Id) + storeChannel <- result + close(storeChannel) + return + } + + app.PreSave() + if result.Err = app.IsValid(); result.Err != nil { + storeChannel <- result + close(storeChannel) + return + } + + if err := as.GetMaster().Insert(app); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.SaveApp", "We couldn't save the app.", "app_id="+app.Id+", "+err.Error()) + } else { + result.Data = app + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (as SqlOAuthStore) UpdateApp(app *model.OAuthApp) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + app.PreUpdate() + + if result.Err = app.IsValid(); result.Err != nil { + storeChannel <- result + close(storeChannel) + return + } + + if oldAppResult, err := as.GetMaster().Get(model.OAuthApp{}, app.Id); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.UpdateApp", "We encounted an error finding the app", "app_id="+app.Id+", "+err.Error()) + } else if oldAppResult == nil { + result.Err = model.NewAppError("SqlOAuthStore.UpdateApp", "We couldn't find the existing app to update", "app_id="+app.Id) + } else { + oldApp := oldAppResult.(*model.OAuthApp) + app.CreateAt = oldApp.CreateAt + app.ClientSecret = oldApp.ClientSecret + app.CreatorId = oldApp.CreatorId + + if count, err := as.GetMaster().Update(app); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.UpdateApp", "We encounted an error updating the app", "app_id="+app.Id+", "+err.Error()) + } else if count != 1 { + result.Err = model.NewAppError("SqlOAuthStore.UpdateApp", "We couldn't update the app", "app_id="+app.Id) + } else { + result.Data = [2]*model.OAuthApp{app, oldApp} + } + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (as SqlOAuthStore) GetApp(id string) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + if obj, err := as.GetReplica().Get(model.OAuthApp{}, id); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.GetApp", "We encounted an error finding the app", "app_id="+id+", "+err.Error()) + } else if obj == nil { + result.Err = model.NewAppError("SqlOAuthStore.GetApp", "We couldn't find the existing app", "app_id="+id) + } else { + result.Data = obj.(*model.OAuthApp) + } + + storeChannel <- result + close(storeChannel) + + }() + + return storeChannel +} + +func (as SqlOAuthStore) GetAppByUser(userId string) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + var apps []*model.OAuthApp + + if _, err := as.GetReplica().Select(&apps, "SELECT * FROM OAuthApps WHERE CreatorId = :UserId", map[string]interface{}{"UserId": userId}); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.GetAppByUser", "We couldn't find any existing apps", "user_id="+userId+", "+err.Error()) + } + + result.Data = apps + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (as SqlOAuthStore) SaveAccessData(accessData *model.AccessData) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + if result.Err = accessData.IsValid(); result.Err != nil { + storeChannel <- result + close(storeChannel) + return + } + + if err := as.GetMaster().Insert(accessData); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.SaveAccessData", "We couldn't save the access token.", err.Error()) + } else { + result.Data = accessData + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (as SqlOAuthStore) GetAccessData(token string) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + accessData := model.AccessData{} + + if err := as.GetReplica().SelectOne(&accessData, "SELECT * FROM OAuthAccessData WHERE Token = :Token", map[string]interface{}{"Token": token}); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.GetAccessData", "We encounted an error finding the access token", err.Error()) + } else { + result.Data = &accessData + } + + storeChannel <- result + close(storeChannel) + + }() + + return storeChannel +} + +func (as SqlOAuthStore) GetAccessDataByAuthCode(authCode string) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + accessData := model.AccessData{} + + if err := as.GetReplica().SelectOne(&accessData, "SELECT * FROM OAuthAccessData WHERE AuthCode = :AuthCode", map[string]interface{}{"AuthCode": authCode}); err != nil { + if strings.Contains(err.Error(), "no rows") { + result.Data = nil + } else { + result.Err = model.NewAppError("SqlOAuthStore.GetAccessDataByAuthCode", "We encountered an error finding the access token", err.Error()) + } + } else { + result.Data = &accessData + } + + storeChannel <- result + close(storeChannel) + + }() + + return storeChannel +} + +func (as SqlOAuthStore) RemoveAccessData(token string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + if _, err := as.GetMaster().Exec("DELETE FROM OAuthAccessData WHERE Token = :Token", map[string]interface{}{"Token": token}); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.RemoveAccessData", "We couldn't remove the access token", "err="+err.Error()) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (as SqlOAuthStore) SaveAuthData(authData *model.AuthData) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + authData.PreSave() + if result.Err = authData.IsValid(); result.Err != nil { + storeChannel <- result + close(storeChannel) + return + } + + if err := as.GetMaster().Insert(authData); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.SaveAuthData", "We couldn't save the authorization code.", err.Error()) + } else { + result.Data = authData + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (as SqlOAuthStore) GetAuthData(code string) StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + if obj, err := as.GetReplica().Get(model.AuthData{}, code); err != nil { + result.Err = model.NewAppError("SqlOAuthStore.GetAuthData", "We encounted an error finding the authorization code", err.Error()) + } else if obj == nil { + result.Err = model.NewAppError("SqlOAuthStore.GetAuthData", "We couldn't find the existing authorization code", "") + } else { + result.Data = obj.(*model.AuthData) + } + + storeChannel <- result + close(storeChannel) + + }() + + return storeChannel +} + +func (as SqlOAuthStore) RemoveAuthData(code string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + _, err := as.GetMaster().Exec("DELETE FROM OAuthAuthData WHERE Code = :Code", map[string]interface{}{"Code": code}) + if err != nil { + result.Err = model.NewAppError("SqlOAuthStore.RemoveAuthData", "We couldn't remove the authorization code", "err="+err.Error()) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} diff --git a/store/sql_oauth_store_test.go b/store/sql_oauth_store_test.go new file mode 100644 index 000000000..08e1388e0 --- /dev/null +++ b/store/sql_oauth_store_test.go @@ -0,0 +1,182 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +package store + +import ( + "github.com/mattermost/platform/model" + "testing" +) + +func TestOAuthStoreSaveApp(t *testing.T) { + Setup() + + a1 := model.OAuthApp{} + a1.CreatorId = model.NewId() + a1.Name = "TestApp" + model.NewId() + a1.CallbackUrls = []string{"https://nowhere.com"} + a1.Homepage = "https://nowhere.com" + + if err := (<-store.OAuth().SaveApp(&a1)).Err; err != nil { + t.Fatal(err) + } +} + +func TestOAuthStoreGetApp(t *testing.T) { + Setup() + + a1 := model.OAuthApp{} + a1.CreatorId = model.NewId() + a1.Name = "TestApp" + model.NewId() + a1.CallbackUrls = []string{"https://nowhere.com"} + a1.Homepage = "https://nowhere.com" + Must(store.OAuth().SaveApp(&a1)) + + if err := (<-store.OAuth().GetApp(a1.Id)).Err; err != nil { + t.Fatal(err) + } + + if err := (<-store.OAuth().GetAppByUser(a1.CreatorId)).Err; err != nil { + t.Fatal(err) + } +} + +func TestOAuthStoreUpdateApp(t *testing.T) { + Setup() + + a1 := model.OAuthApp{} + a1.CreatorId = model.NewId() + a1.Name = "TestApp" + model.NewId() + a1.CallbackUrls = []string{"https://nowhere.com"} + a1.Homepage = "https://nowhere.com" + Must(store.OAuth().SaveApp(&a1)) + + a1.CreateAt = 1 + a1.ClientSecret = "pwd" + a1.CreatorId = "12345678901234567890123456" + a1.Name = "NewName" + if result := <-store.OAuth().UpdateApp(&a1); result.Err != nil { + t.Fatal(result.Err) + } else { + ua1 := (result.Data.([2]*model.OAuthApp)[0]) + if ua1.Name != "NewName" { + t.Fatal("name did not update") + } + if ua1.CreateAt == 1 { + t.Fatal("create at should not have updated") + } + if ua1.ClientSecret == "pwd" { + t.Fatal("client secret should not have updated") + } + if ua1.CreatorId == "12345678901234567890123456" { + t.Fatal("creator id should not have updated") + } + } +} + +func TestOAuthStoreSaveAccessData(t *testing.T) { + Setup() + + a1 := model.AccessData{} + a1.AuthCode = model.NewId() + a1.Token = model.NewId() + a1.RefreshToken = model.NewId() + + if err := (<-store.OAuth().SaveAccessData(&a1)).Err; err != nil { + t.Fatal(err) + } +} + +func TestOAuthStoreGetAccessData(t *testing.T) { + Setup() + + a1 := model.AccessData{} + a1.AuthCode = model.NewId() + a1.Token = model.NewId() + a1.RefreshToken = model.NewId() + Must(store.OAuth().SaveAccessData(&a1)) + + if result := <-store.OAuth().GetAccessData(a1.Token); result.Err != nil { + t.Fatal(result.Err) + } else { + ra1 := result.Data.(*model.AccessData) + if a1.Token != ra1.Token { + t.Fatal("tokens didn't match") + } + } + + if err := (<-store.OAuth().GetAccessDataByAuthCode(a1.AuthCode)).Err; err != nil { + t.Fatal(err) + } + + if err := (<-store.OAuth().GetAccessDataByAuthCode("junk")).Err; err != nil { + t.Fatal(err) + } +} + +func TestOAuthStoreRemoveAccessData(t *testing.T) { + Setup() + + a1 := model.AccessData{} + a1.AuthCode = model.NewId() + a1.Token = model.NewId() + a1.RefreshToken = model.NewId() + Must(store.OAuth().SaveAccessData(&a1)) + + if err := (<-store.OAuth().RemoveAccessData(a1.Token)).Err; err != nil { + t.Fatal(err) + } + + if result := <-store.OAuth().GetAccessDataByAuthCode(a1.AuthCode); result.Err != nil { + t.Fatal(result.Err) + } else { + if result.Data != nil { + t.Fatal("did not delete access token") + } + } +} + +func TestOAuthStoreSaveAuthData(t *testing.T) { + Setup() + + a1 := model.AuthData{} + a1.ClientId = model.NewId() + a1.UserId = model.NewId() + a1.Code = model.NewId() + + if err := (<-store.OAuth().SaveAuthData(&a1)).Err; err != nil { + t.Fatal(err) + } +} + +func TestOAuthStoreGetAuthData(t *testing.T) { + Setup() + + a1 := model.AuthData{} + a1.ClientId = model.NewId() + a1.UserId = model.NewId() + a1.Code = model.NewId() + Must(store.OAuth().SaveAuthData(&a1)) + + if err := (<-store.OAuth().GetAuthData(a1.Code)).Err; err != nil { + t.Fatal(err) + } +} + +func TestOAuthStoreRemoveAuthData(t *testing.T) { + Setup() + + a1 := model.AuthData{} + a1.ClientId = model.NewId() + a1.UserId = model.NewId() + a1.Code = model.NewId() + Must(store.OAuth().SaveAuthData(&a1)) + + if err := (<-store.OAuth().RemoveAuthData(a1.Code)).Err; err != nil { + t.Fatal(err) + } + + if err := (<-store.OAuth().GetAuthData(a1.Code)).Err; err == nil { + t.Fatal("should have errored - auth code removed") + } +} diff --git a/store/sql_session_store.go b/store/sql_session_store.go index 12004ab78..c1d2c852b 100644 --- a/store/sql_session_store.go +++ b/store/sql_session_store.go @@ -18,7 +18,7 @@ func NewSqlSessionStore(sqlStore *SqlStore) SessionStore { for _, db := range sqlStore.GetAllConns() { table := db.AddTableWithName(model.Session{}, "Sessions").SetKeys(false, "Id") table.ColMap("Id").SetMaxSize(26) - table.ColMap("AltId").SetMaxSize(26) + table.ColMap("Token").SetMaxSize(26) table.ColMap("UserId").SetMaxSize(26) table.ColMap("TeamId").SetMaxSize(26) table.ColMap("DeviceId").SetMaxSize(128) @@ -34,7 +34,7 @@ func (me SqlSessionStore) UpgradeSchemaIfNeeded() { func (me SqlSessionStore) CreateIndexesIfNotExists() { me.CreateIndexIfNotExists("idx_sessions_user_id", "Sessions", "UserId") - me.CreateIndexIfNotExists("idx_sessions_alt_id", "Sessions", "AltId") + me.CreateIndexIfNotExists("idx_sessions_token", "Sessions", "Token") } func (me SqlSessionStore) Save(session *model.Session) StoreChannel { @@ -70,19 +70,21 @@ func (me SqlSessionStore) Save(session *model.Session) StoreChannel { return storeChannel } -func (me SqlSessionStore) Get(id string) StoreChannel { +func (me SqlSessionStore) Get(sessionIdOrToken string) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} - if obj, err := me.GetReplica().Get(model.Session{}, id); err != nil { - result.Err = model.NewAppError("SqlSessionStore.Get", "We encounted an error finding the session", "id="+id+", "+err.Error()) - } else if obj == nil { - result.Err = model.NewAppError("SqlSessionStore.Get", "We couldn't find the existing session", "id="+id) + var sessions []*model.Session + + if _, err := me.GetReplica().Select(&sessions, "SELECT * FROM Sessions WHERE Token = :Token OR Id = :Id LIMIT 1", map[string]interface{}{"Token": sessionIdOrToken, "Id": sessionIdOrToken}); err != nil { + result.Err = model.NewAppError("SqlSessionStore.Get", "We encounted an error finding the session", "sessionIdOrToken="+sessionIdOrToken+", "+err.Error()) + } else if sessions == nil || len(sessions) == 0 { + result.Err = model.NewAppError("SqlSessionStore.Get", "We encounted an error finding the session", "sessionIdOrToken="+sessionIdOrToken) } else { - result.Data = obj.(*model.Session) + result.Data = sessions[0] } storeChannel <- result @@ -120,15 +122,15 @@ func (me SqlSessionStore) GetSessions(userId string) StoreChannel { return storeChannel } -func (me SqlSessionStore) Remove(sessionIdOrAlt string) StoreChannel { +func (me SqlSessionStore) Remove(sessionIdOrToken string) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} - _, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE Id = :Id Or AltId = :AltId", map[string]interface{}{"Id": sessionIdOrAlt, "AltId": sessionIdOrAlt}) + _, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE Id = :Id Or Token = :Token", map[string]interface{}{"Id": sessionIdOrToken, "Token": sessionIdOrToken}) if err != nil { - result.Err = model.NewAppError("SqlSessionStore.RemoveSession", "We couldn't remove the session", "id="+sessionIdOrAlt+", err="+err.Error()) + result.Err = model.NewAppError("SqlSessionStore.RemoveSession", "We couldn't remove the session", "id="+sessionIdOrToken+", err="+err.Error()) } storeChannel <- result @@ -181,7 +183,6 @@ func (me SqlSessionStore) UpdateRoles(userId, roles string) StoreChannel { go func() { result := StoreResult{} - if _, err := me.GetMaster().Exec("UPDATE Sessions SET Roles = :Roles WHERE UserId = :UserId", map[string]interface{}{"Roles": roles, "UserId": userId}); err != nil { result.Err = model.NewAppError("SqlSessionStore.UpdateRoles", "We couldn't update the roles", "userId="+userId) } else { diff --git a/store/sql_session_store_test.go b/store/sql_session_store_test.go index 581aff971..4ae680556 100644 --- a/store/sql_session_store_test.go +++ b/store/sql_session_store_test.go @@ -80,7 +80,7 @@ func TestSessionRemove(t *testing.T) { } } -func TestSessionRemoveAlt(t *testing.T) { +func TestSessionRemoveToken(t *testing.T) { Setup() s1 := model.Session{} @@ -96,7 +96,7 @@ func TestSessionRemoveAlt(t *testing.T) { } } - Must(store.Session().Remove(s1.AltId)) + Must(store.Session().Remove(s1.Token)) if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil { t.Fatal("should have been removed") diff --git a/store/sql_store.go b/store/sql_store.go index 98c67d668..c0b3c2021 100644 --- a/store/sql_store.go +++ b/store/sql_store.go @@ -38,6 +38,7 @@ type SqlStore struct { user UserStore audit AuditStore session SessionStore + oauth OAuthStore } func NewSqlStore() Store { @@ -55,28 +56,36 @@ func NewSqlStore() Store { utils.Cfg.SqlSettings.Trace) } + // Temporary upgrade code, remove after 0.8.0 release + if sqlStore.DoesColumnExist("Sessions", "AltId") { + sqlStore.GetMaster().Exec("DROP TABLE IF EXISTS Sessions") + } + sqlStore.team = NewSqlTeamStore(sqlStore) sqlStore.channel = NewSqlChannelStore(sqlStore) sqlStore.post = NewSqlPostStore(sqlStore) sqlStore.user = NewSqlUserStore(sqlStore) sqlStore.audit = NewSqlAuditStore(sqlStore) sqlStore.session = NewSqlSessionStore(sqlStore) + sqlStore.oauth = NewSqlOAuthStore(sqlStore) sqlStore.master.CreateTablesIfNotExists() - sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists() - sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists() - sqlStore.post.(*SqlPostStore).CreateIndexesIfNotExists() - sqlStore.user.(*SqlUserStore).CreateIndexesIfNotExists() - sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists() - sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists() - sqlStore.team.(*SqlTeamStore).UpgradeSchemaIfNeeded() sqlStore.channel.(*SqlChannelStore).UpgradeSchemaIfNeeded() sqlStore.post.(*SqlPostStore).UpgradeSchemaIfNeeded() sqlStore.user.(*SqlUserStore).UpgradeSchemaIfNeeded() sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded() sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded() + sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded() + + sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists() + sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists() + sqlStore.post.(*SqlPostStore).CreateIndexesIfNotExists() + sqlStore.user.(*SqlUserStore).CreateIndexesIfNotExists() + sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists() + sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists() + sqlStore.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists() return sqlStore } @@ -363,6 +372,10 @@ func (ss SqlStore) Audit() AuditStore { return ss.audit } +func (ss SqlStore) OAuth() OAuthStore { + return ss.oauth +} + type mattermConverter struct{} func (me mattermConverter) ToDb(val interface{}) (interface{}, error) { diff --git a/store/store.go b/store/store.go index 959e93fa4..0218bc757 100644 --- a/store/store.go +++ b/store/store.go @@ -34,6 +34,7 @@ type Store interface { User() UserStore Audit() AuditStore Session() SessionStore + OAuth() OAuthStore Close() } @@ -104,9 +105,9 @@ type UserStore interface { type SessionStore interface { Save(session *model.Session) StoreChannel - Get(id string) StoreChannel + Get(sessionIdOrToken string) StoreChannel GetSessions(userId string) StoreChannel - Remove(sessionIdOrAlt string) StoreChannel + Remove(sessionIdOrToken string) StoreChannel UpdateLastActivityAt(sessionId string, time int64) StoreChannel UpdateRoles(userId string, roles string) StoreChannel } @@ -115,3 +116,17 @@ type AuditStore interface { Save(audit *model.Audit) StoreChannel Get(user_id string, limit int) StoreChannel } + +type OAuthStore interface { + SaveApp(app *model.OAuthApp) StoreChannel + UpdateApp(app *model.OAuthApp) StoreChannel + GetApp(id string) StoreChannel + GetAppByUser(userId string) StoreChannel + SaveAuthData(authData *model.AuthData) StoreChannel + GetAuthData(code string) StoreChannel + RemoveAuthData(code string) StoreChannel + SaveAccessData(accessData *model.AccessData) StoreChannel + GetAccessData(token string) StoreChannel + GetAccessDataByAuthCode(authCode string) StoreChannel + RemoveAccessData(token string) StoreChannel +} -- cgit v1.2.3-1-g7c22