summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2015-09-22 15:47:57 -0400
committerJoram Wilander <jwawilander@gmail.com>2015-09-22 15:47:57 -0400
commitac7918c5540900ab0dbe43d61b8c1155e4279b55 (patch)
tree2e519e101e995d24d656d7cf1f7a9d404303a364 /store
parenta44e8f0cd904d386caea410398dcaf7dbfd9c138 (diff)
parent98186e5018bbc604796d4f9762c93f4f75e2913f (diff)
downloadchat-ac7918c5540900ab0dbe43d61b8c1155e4279b55.tar.gz
chat-ac7918c5540900ab0dbe43d61b8c1155e4279b55.tar.bz2
chat-ac7918c5540900ab0dbe43d61b8c1155e4279b55.zip
Merge pull request #715 from mattermost/plt-27
PLT-27 Implement incoming webhooks.
Diffstat (limited to 'store')
-rw-r--r--store/sql_store.go8
-rw-r--r--store/sql_webhook_store.go128
-rw-r--r--store/sql_webhook_store_test.go77
-rw-r--r--store/store.go8
4 files changed, 221 insertions, 0 deletions
diff --git a/store/sql_store.go b/store/sql_store.go
index adac47b4d..98703841a 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -40,6 +40,7 @@ type SqlStore struct {
session SessionStore
oauth OAuthStore
system SystemStore
+ webhook WebhookStore
}
func NewSqlStore() Store {
@@ -91,6 +92,7 @@ func NewSqlStore() Store {
sqlStore.session = NewSqlSessionStore(sqlStore)
sqlStore.oauth = NewSqlOAuthStore(sqlStore)
sqlStore.system = NewSqlSystemStore(sqlStore)
+ sqlStore.webhook = NewSqlWebhookStore(sqlStore)
sqlStore.master.CreateTablesIfNotExists()
@@ -102,6 +104,7 @@ func NewSqlStore() Store {
sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded()
sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded()
sqlStore.system.(*SqlSystemStore).UpgradeSchemaIfNeeded()
+ sqlStore.webhook.(*SqlWebhookStore).UpgradeSchemaIfNeeded()
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
@@ -111,6 +114,7 @@ func NewSqlStore() Store {
sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists()
sqlStore.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists()
sqlStore.system.(*SqlSystemStore).CreateIndexesIfNotExists()
+ sqlStore.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists()
if model.IsPreviousVersion(schemaVersion) {
sqlStore.system.Update(&model.System{Name: "Version", Value: model.CurrentVersion})
@@ -469,6 +473,10 @@ func (ss SqlStore) System() SystemStore {
return ss.system
}
+func (ss SqlStore) Webhook() WebhookStore {
+ return ss.webhook
+}
+
type mattermConverter struct{}
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {
diff --git a/store/sql_webhook_store.go b/store/sql_webhook_store.go
new file mode 100644
index 000000000..e309f79e4
--- /dev/null
+++ b/store/sql_webhook_store.go
@@ -0,0 +1,128 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package store
+
+import (
+ "github.com/mattermost/platform/model"
+)
+
+type SqlWebhookStore struct {
+ *SqlStore
+}
+
+func NewSqlWebhookStore(sqlStore *SqlStore) WebhookStore {
+ s := &SqlWebhookStore{sqlStore}
+
+ for _, db := range sqlStore.GetAllConns() {
+ table := db.AddTableWithName(model.IncomingWebhook{}, "IncomingWebhooks").SetKeys(false, "Id")
+ table.ColMap("Id").SetMaxSize(26)
+ table.ColMap("UserId").SetMaxSize(26)
+ table.ColMap("ChannelId").SetMaxSize(26)
+ table.ColMap("TeamId").SetMaxSize(26)
+ }
+
+ return s
+}
+
+func (s SqlWebhookStore) UpgradeSchemaIfNeeded() {
+}
+
+func (s SqlWebhookStore) CreateIndexesIfNotExists() {
+ s.CreateIndexIfNotExists("idx_webhook_user_id", "IncomingWebhooks", "UserId")
+ s.CreateIndexIfNotExists("idx_webhook_team_id", "IncomingWebhooks", "TeamId")
+}
+
+func (s SqlWebhookStore) SaveIncoming(webhook *model.IncomingWebhook) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ if len(webhook.Id) > 0 {
+ result.Err = model.NewAppError("SqlWebhookStore.SaveIncoming",
+ "You cannot overwrite an existing IncomingWebhook", "id="+webhook.Id)
+ storeChannel <- result
+ close(storeChannel)
+ return
+ }
+
+ webhook.PreSave()
+ if result.Err = webhook.IsValid(); result.Err != nil {
+ storeChannel <- result
+ close(storeChannel)
+ return
+ }
+
+ if err := s.GetMaster().Insert(webhook); err != nil {
+ result.Err = model.NewAppError("SqlWebhookStore.SaveIncoming", "We couldn't save the IncomingWebhook", "id="+webhook.Id+", "+err.Error())
+ } else {
+ result.Data = webhook
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
+func (s SqlWebhookStore) GetIncoming(id string) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ var webhook model.IncomingWebhook
+
+ if err := s.GetReplica().SelectOne(&webhook, "SELECT * FROM IncomingWebhooks WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id}); err != nil {
+ result.Err = model.NewAppError("SqlWebhookStore.GetIncoming", "We couldn't get the webhook", "id="+id+", err="+err.Error())
+ }
+
+ result.Data = &webhook
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
+func (s SqlWebhookStore) DeleteIncoming(webhookId string, time int64) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ _, err := s.GetMaster().Exec("Update IncomingWebhooks SET DeleteAt = :DeleteAt, UpdateAt = :UpdateAt WHERE Id = :Id", map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": webhookId})
+ if err != nil {
+ result.Err = model.NewAppError("SqlWebhookStore.DeleteIncoming", "We couldn't delete the webhook", "id="+webhookId+", err="+err.Error())
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
+func (s SqlWebhookStore) GetIncomingByUser(userId string) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ var webhooks []*model.IncomingWebhook
+
+ if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE UserId = :UserId AND DeleteAt = 0", map[string]interface{}{"UserId": userId}); err != nil {
+ result.Err = model.NewAppError("SqlWebhookStore.GetIncomingByUser", "We couldn't get the webhook", "userId="+userId+", err="+err.Error())
+ }
+
+ result.Data = webhooks
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
diff --git a/store/sql_webhook_store_test.go b/store/sql_webhook_store_test.go
new file mode 100644
index 000000000..0a015eaf9
--- /dev/null
+++ b/store/sql_webhook_store_test.go
@@ -0,0 +1,77 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package store
+
+import (
+ "github.com/mattermost/platform/model"
+ "testing"
+)
+
+func TestIncomingWebhookStoreSaveIncoming(t *testing.T) {
+ Setup()
+
+ o1 := model.IncomingWebhook{}
+ o1.ChannelId = model.NewId()
+ o1.UserId = model.NewId()
+ o1.TeamId = model.NewId()
+
+ if err := (<-store.Webhook().SaveIncoming(&o1)).Err; err != nil {
+ t.Fatal("couldn't save item", err)
+ }
+
+ if err := (<-store.Webhook().SaveIncoming(&o1)).Err; err == nil {
+ t.Fatal("shouldn't be able to update from save")
+ }
+}
+
+func TestIncomingWebhookStoreGetIncoming(t *testing.T) {
+ Setup()
+
+ o1 := &model.IncomingWebhook{}
+ o1.ChannelId = model.NewId()
+ o1.UserId = model.NewId()
+ o1.TeamId = model.NewId()
+
+ o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook)
+
+ if r1 := <-store.Webhook().GetIncoming(o1.Id); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ if r1.Data.(*model.IncomingWebhook).CreateAt != o1.CreateAt {
+ t.Fatal("invalid returned webhook")
+ }
+ }
+
+ if err := (<-store.Webhook().GetIncoming("123")).Err; err == nil {
+ t.Fatal("Missing id should have failed")
+ }
+}
+
+func TestIncomingWebhookStoreDelete(t *testing.T) {
+ Setup()
+
+ o1 := &model.IncomingWebhook{}
+ o1.ChannelId = model.NewId()
+ o1.UserId = model.NewId()
+ o1.TeamId = model.NewId()
+
+ o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook)
+
+ if r1 := <-store.Webhook().GetIncoming(o1.Id); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ if r1.Data.(*model.IncomingWebhook).CreateAt != o1.CreateAt {
+ t.Fatal("invalid returned webhook")
+ }
+ }
+
+ if r2 := <-store.Webhook().DeleteIncoming(o1.Id, model.GetMillis()); r2.Err != nil {
+ t.Fatal(r2.Err)
+ }
+
+ if r3 := (<-store.Webhook().GetIncoming(o1.Id)); r3.Err == nil {
+ t.Log(r3.Data)
+ t.Fatal("Missing id should have failed")
+ }
+}
diff --git a/store/store.go b/store/store.go
index 1344c4ebe..c9d40cfa5 100644
--- a/store/store.go
+++ b/store/store.go
@@ -36,6 +36,7 @@ type Store interface {
Session() SessionStore
OAuth() OAuthStore
System() SystemStore
+ Webhook() WebhookStore
Close()
}
@@ -137,3 +138,10 @@ type SystemStore interface {
Update(system *model.System) StoreChannel
Get() StoreChannel
}
+
+type WebhookStore interface {
+ SaveIncoming(webhook *model.IncomingWebhook) StoreChannel
+ GetIncoming(id string) StoreChannel
+ GetIncomingByUser(userId string) StoreChannel
+ DeleteIncoming(webhookId string, time int64) StoreChannel
+}