Adjust message api to use new app/client id
This commit is contained in:
parent
433a83823b
commit
6dda2606d4
|
|
@ -0,0 +1,15 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func withID(ctx *gin.Context, name string, f func(id uint)) {
|
||||
if id, err := strconv.ParseUint(ctx.Param(name), 10, 32); err == nil {
|
||||
f(uint(id));
|
||||
} else {
|
||||
ctx.AbortWithError(400, errors.New("invalid id"))
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package api
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
|
@ -12,14 +11,15 @@ import (
|
|||
|
||||
// The MessageDatabase interface for encapsulating database access.
|
||||
type MessageDatabase interface {
|
||||
GetMessagesByApplication(tokenID string) []*model.Message
|
||||
GetApplicationByID(id string) *model.Application
|
||||
GetMessagesByApplication(id uint) []*model.Message
|
||||
GetApplicationByID(id uint) *model.Application
|
||||
GetMessagesByUser(userID uint) []*model.Message
|
||||
DeleteMessageByID(id uint) error
|
||||
GetMessageByID(id uint) *model.Message
|
||||
DeleteMessagesByUser(userID uint) error
|
||||
DeleteMessagesByApplication(applicationID string) error
|
||||
DeleteMessagesByApplication(applicationID uint) error
|
||||
CreateMessage(message *model.Message) error
|
||||
GetApplicationByToken(token string) *model.Application
|
||||
}
|
||||
|
||||
// Notifier notifies when a new message was created.
|
||||
|
|
@ -42,9 +42,10 @@ func (a *MessageAPI) GetMessages(ctx *gin.Context) {
|
|||
|
||||
// GetMessagesWithApplication returns all messages from a specific application.
|
||||
func (a *MessageAPI) GetMessagesWithApplication(ctx *gin.Context) {
|
||||
appID := ctx.Param("appid")
|
||||
messages := a.DB.GetMessagesByApplication(appID)
|
||||
withID(ctx, "appid", func(id uint) {
|
||||
messages := a.DB.GetMessagesByApplication(id)
|
||||
ctx.JSON(200, messages)
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteMessages delete all messages from a user.
|
||||
|
|
@ -55,33 +56,31 @@ func (a *MessageAPI) DeleteMessages(ctx *gin.Context) {
|
|||
|
||||
// DeleteMessageWithApplication deletes all messages from a specific application.
|
||||
func (a *MessageAPI) DeleteMessageWithApplication(ctx *gin.Context) {
|
||||
appID := ctx.Param("appid")
|
||||
if application := a.DB.GetApplicationByID(appID); application != nil && application.UserID == auth.GetUserID(ctx) {
|
||||
a.DB.DeleteMessagesByApplication(appID)
|
||||
withID(ctx, "appid", func(id uint) {
|
||||
if application := a.DB.GetApplicationByID(id); application != nil && application.UserID == auth.GetUserID(ctx) {
|
||||
a.DB.DeleteMessagesByApplication(id)
|
||||
} else {
|
||||
ctx.AbortWithError(404, errors.New("application does not exists"))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// DeleteMessage deletes a message with an id.
|
||||
func (a *MessageAPI) DeleteMessage(ctx *gin.Context) {
|
||||
id := ctx.Param("id")
|
||||
if parsedUInt, err := strconv.ParseUint(id, 10, 32); err == nil {
|
||||
if msg := a.DB.GetMessageByID(uint(parsedUInt)); msg != nil && a.DB.GetApplicationByID(msg.ApplicationID).UserID == auth.GetUserID(ctx) {
|
||||
a.DB.DeleteMessageByID(uint(parsedUInt))
|
||||
withID(ctx, "id", func(id uint) {
|
||||
if msg := a.DB.GetMessageByID(id); msg != nil && a.DB.GetApplicationByID(msg.ApplicationID).UserID == auth.GetUserID(ctx) {
|
||||
a.DB.DeleteMessageByID(id)
|
||||
} else {
|
||||
ctx.AbortWithError(404, errors.New("message does not exists"))
|
||||
}
|
||||
} else {
|
||||
ctx.AbortWithError(400, errors.New("message does not exist"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateMessage creates a message, authentication via application-token is required.
|
||||
func (a *MessageAPI) CreateMessage(ctx *gin.Context) {
|
||||
message := model.Message{}
|
||||
if err := ctx.Bind(&message); err == nil {
|
||||
message.ApplicationID = auth.GetTokenID(ctx)
|
||||
message.ApplicationID = a.DB.GetApplicationByToken(auth.GetTokenID(ctx)).ID
|
||||
message.Date = time.Now()
|
||||
a.DB.CreateMessage(&message)
|
||||
a.Notifier.Notify(auth.GetUserID(ctx), &message)
|
||||
|
|
|
|||
|
|
@ -46,27 +46,27 @@ func (s *MessageSuite) Notify(userID uint, msg *model.Message) {
|
|||
func (s *MessageSuite) Test_GetMessages() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 5, "")
|
||||
t, _ := time.Parse("2006/01/02", "2017/01/02")
|
||||
s.db.On("GetMessagesByUser", uint(5)).Return([]*model.Message{{ID: 1, ApplicationID: "asd", Message: "OH HELLO THERE", Date: t, Title: "wup", Priority: 2}, {ID: 2, ApplicationID: "cloud", Message: "hi", Title: "hi", Date: t, Priority: 4}})
|
||||
s.db.On("GetMessagesByUser", uint(5)).Return([]*model.Message{{ID: 1, ApplicationID: 1, Message: "OH HELLO THERE", Date: t, Title: "wup", Priority: 2}, {ID: 2, ApplicationID: 2, Message: "hi", Title: "hi", Date: t, Priority: 4}})
|
||||
|
||||
s.a.GetMessages(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
||||
|
||||
assert.JSONEq(s.T(), `[{"id":1,"appid":"asd","message":"OH HELLO THERE","title":"wup","priority":2,"date":"2017-01-02T00:00:00Z"},{"id":2,"appid":"cloud","message":"hi","title":"hi","priority":4,"date":"2017-01-02T00:00:00Z"}]`, string(bytes))
|
||||
assert.JSONEq(s.T(), `[{"id":1,"appid":1,"message":"OH HELLO THERE","title":"wup","priority":2,"date":"2017-01-02T00:00:00Z"},{"id":2,"appid":2,"message":"hi","title":"hi","priority":4,"date":"2017-01-02T00:00:00Z"}]`, string(bytes))
|
||||
}
|
||||
|
||||
func (s *MessageSuite) Test_GetMessagesWithToken() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 4, "")
|
||||
t, _ := time.Parse("2006/01/02", "2021/01/02")
|
||||
s.db.On("GetMessagesByApplication", "mytoken").Return([]*model.Message{{ID: 2, ApplicationID: "mytoken", Message: "hi", Title: "hi", Date: t, Priority: 4}})
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "mytoken"}}
|
||||
s.db.On("GetMessagesByApplication", uint(1)).Return([]*model.Message{{ID: 2, ApplicationID: 1, Message: "hi", Title: "hi", Date: t, Priority: 4}})
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "1"}}
|
||||
|
||||
s.a.GetMessagesWithApplication(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
||||
assert.JSONEq(s.T(), `[{"id":2,"appid":"mytoken","message":"hi","title":"hi","priority":4,"date":"2021-01-02T00:00:00Z"}]`, string(bytes))
|
||||
assert.JSONEq(s.T(), `[{"id":2,"appid":1,"message":"hi","title":"hi","priority":4,"date":"2021-01-02T00:00:00Z"}]`, string(bytes))
|
||||
}
|
||||
|
||||
func (s *MessageSuite) Test_DeleteMessage_invalidID() {
|
||||
|
|
@ -89,8 +89,8 @@ func (s *MessageSuite) Test_DeleteMessage_notExistingID() {
|
|||
func (s *MessageSuite) Test_DeleteMessage_existingIDButNotOwner() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 6, "")
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
||||
s.db.On("GetMessageByID", uint(1)).Return(&model.Message{ID: 1, ApplicationID: "token"})
|
||||
s.db.On("GetApplicationByID", "token").Return(&model.Application{ID: "token", UserID: 2})
|
||||
s.db.On("GetMessageByID", uint(1)).Return(&model.Message{ID: 1, ApplicationID: 1})
|
||||
s.db.On("GetApplicationByID", uint(1)).Return(&model.Application{ID: 1, Token: "token", UserID: 2})
|
||||
|
||||
s.a.DeleteMessage(s.ctx)
|
||||
|
||||
|
|
@ -100,8 +100,8 @@ func (s *MessageSuite) Test_DeleteMessage_existingIDButNotOwner() {
|
|||
func (s *MessageSuite) Test_DeleteMessage() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 2, "")
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
||||
s.db.On("GetMessageByID", uint(1)).Return(&model.Message{ID: 1, ApplicationID: "token"})
|
||||
s.db.On("GetApplicationByID", "token").Return(&model.Application{ID: "token", UserID: 2})
|
||||
s.db.On("GetMessageByID", uint(1)).Return(&model.Message{ID: 1, ApplicationID: 5})
|
||||
s.db.On("GetApplicationByID", uint(5)).Return(&model.Application{ID: 5, Token: "token", UserID: 2})
|
||||
s.db.On("DeleteMessageByID", uint(1)).Return(nil)
|
||||
|
||||
s.a.DeleteMessage(s.ctx)
|
||||
|
|
@ -112,37 +112,37 @@ func (s *MessageSuite) Test_DeleteMessage() {
|
|||
|
||||
func (s *MessageSuite) Test_DeleteMessageWithToken() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 2, "")
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "mytoken"}}
|
||||
s.db.On("GetApplicationByID", "mytoken").Return(&model.Application{ID: "mytoken", UserID: 2})
|
||||
s.db.On("DeleteMessagesByApplication", "mytoken").Return(nil)
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "5"}}
|
||||
s.db.On("GetApplicationByID", uint(5)).Return(&model.Application{ID: 5, Token: "mytoken", UserID: 2})
|
||||
s.db.On("DeleteMessagesByApplication", uint(5)).Return(nil)
|
||||
|
||||
s.a.DeleteMessageWithApplication(s.ctx)
|
||||
|
||||
s.db.AssertCalled(s.T(), "DeleteMessagesByApplication", "mytoken")
|
||||
s.db.AssertCalled(s.T(), "DeleteMessagesByApplication", uint(5))
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *MessageSuite) Test_DeleteMessageWithToken_notExistingToken() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 2, "")
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "asdasdasd"}}
|
||||
s.db.On("GetApplicationByID", "asdasdasd").Return(nil)
|
||||
s.db.On("DeleteMessagesByApplication", "asdasdasd").Return(nil)
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "55"}}
|
||||
s.db.On("GetApplicationByID", uint(55)).Return(nil)
|
||||
s.db.On("DeleteMessagesByApplication", mock.Anything).Return(nil)
|
||||
|
||||
s.a.DeleteMessageWithApplication(s.ctx)
|
||||
|
||||
s.db.AssertNotCalled(s.T(), "DeleteMessagesByApplication", "mytoken")
|
||||
s.db.AssertNotCalled(s.T(), "DeleteMessagesByApplication", mock.Anything)
|
||||
assert.Equal(s.T(), 404, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *MessageSuite) Test_DeleteMessageWithToken_notOwner() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 4, "")
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "mytoken"}}
|
||||
s.db.On("GetApplicationByID", "mytoken").Return(&model.Application{ID: "mytoken", UserID: 2})
|
||||
s.db.On("DeleteMessagesByApplication", "mytoken").Return(nil)
|
||||
s.ctx.Params = gin.Params{{Key: "appid", Value: "55"}}
|
||||
s.db.On("GetApplicationByID", uint(55)).Return(&model.Application{ID: 55, Token: "mytoken", UserID: 2})
|
||||
s.db.On("DeleteMessagesByApplication", uint(55)).Return(nil)
|
||||
|
||||
s.a.DeleteMessageWithApplication(s.ctx)
|
||||
|
||||
s.db.AssertNotCalled(s.T(), "DeleteMessagesByApplication", "mytoken")
|
||||
s.db.AssertNotCalled(s.T(), "DeleteMessagesByApplication", mock.Anything)
|
||||
assert.Equal(s.T(), 404, s.recorder.Code)
|
||||
}
|
||||
|
||||
|
|
@ -158,11 +158,12 @@ func (s *MessageSuite) Test_DeleteMessages() {
|
|||
|
||||
func (s *MessageSuite) Test_CreateMessage_onJson_allParams() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 4, "app-token")
|
||||
s.db.On("GetApplicationByToken", "app-token").Return(&model.Application{ID: 7})
|
||||
|
||||
t, _ := time.Parse("2006/01/02", "2017/01/02")
|
||||
patch := monkey.Patch(time.Now, func() time.Time { return t })
|
||||
defer patch.Unpatch()
|
||||
expected := &model.Message{ID: 0, ApplicationID: "app-token", Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
|
||||
expected := &model.Message{ID: 0, ApplicationID: 7, Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
|
||||
|
||||
s.ctx.Request = httptest.NewRequest("POST", "/token", strings.NewReader(`{"title": "mytitle", "message": "mymessage", "priority": 1}`))
|
||||
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
||||
|
|
@ -177,11 +178,11 @@ func (s *MessageSuite) Test_CreateMessage_onJson_allParams() {
|
|||
|
||||
func (s *MessageSuite) Test_CreateMessage_onlyRequired() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 4, "app-token")
|
||||
|
||||
s.db.On("GetApplicationByToken", "app-token").Return(&model.Application{ID: 5})
|
||||
t, _ := time.Parse("2006/01/02", "2017/01/02")
|
||||
patch := monkey.Patch(time.Now, func() time.Time { return t })
|
||||
defer patch.Unpatch()
|
||||
expected := &model.Message{ID: 0, ApplicationID: "app-token", Title: "mytitle", Message: "mymessage", Date: t}
|
||||
expected := &model.Message{ID: 0, ApplicationID: 5, Title: "mytitle", Message: "mymessage", Date: t}
|
||||
|
||||
s.ctx.Request = httptest.NewRequest("POST", "/token", strings.NewReader(`{"title": "mytitle", "message": "mymessage"}`))
|
||||
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
||||
|
|
@ -235,11 +236,12 @@ func (s *MessageSuite) Test_CreateMessage_failWhenPriorityNotNumber() {
|
|||
|
||||
func (s *MessageSuite) Test_CreateMessage_onQueryData() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 4, "app-token")
|
||||
s.db.On("GetApplicationByToken", "app-token").Return(&model.Application{ID: 2})
|
||||
|
||||
t, _ := time.Parse("2006/01/02", "2017/01/02")
|
||||
patch := monkey.Patch(time.Now, func() time.Time { return t })
|
||||
defer patch.Unpatch()
|
||||
expected := &model.Message{ID: 0, ApplicationID: "app-token", Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
|
||||
expected := &model.Message{ID: 0, ApplicationID: 2, Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
|
||||
|
||||
s.ctx.Request = httptest.NewRequest("POST", "/token?title=mytitle&message=mymessage&priority=1", nil)
|
||||
s.ctx.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
|
@ -254,11 +256,12 @@ func (s *MessageSuite) Test_CreateMessage_onQueryData() {
|
|||
|
||||
func (s *MessageSuite) Test_CreateMessage_onFormData() {
|
||||
auth.RegisterAuthentication(s.ctx, nil, 4, "app-token")
|
||||
s.db.On("GetApplicationByToken", "app-token").Return(&model.Application{ID: 99})
|
||||
|
||||
t, _ := time.Parse("2006/01/02", "2017/01/02")
|
||||
patch := monkey.Patch(time.Now, func() time.Time { return t })
|
||||
defer patch.Unpatch()
|
||||
expected := &model.Message{ID: 0, ApplicationID: "app-token", Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
|
||||
expected := &model.Message{ID: 0, ApplicationID: 99, Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
|
||||
|
||||
s.ctx.Request = httptest.NewRequest("POST", "/token", strings.NewReader("title=mytitle&message=mymessage&priority=1"))
|
||||
s.ctx.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Code generated by mockery v1.0.0
|
||||
package mock
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import model "github.com/gotify/server/model"
|
||||
import "github.com/stretchr/testify/mock"
|
||||
import "github.com/gotify/server/model"
|
||||
|
||||
// MockMessageDatabase is an autogenerated mock type for the MessageDatabase type
|
||||
type MockMessageDatabase struct {
|
||||
|
|
@ -38,11 +38,11 @@ func (_m *MockMessageDatabase) DeleteMessageByID(id uint) error {
|
|||
}
|
||||
|
||||
// DeleteMessagesByApplication provides a mock function with given fields: applicationID
|
||||
func (_m *MockMessageDatabase) DeleteMessagesByApplication(applicationID string) error {
|
||||
func (_m *MockMessageDatabase) DeleteMessagesByApplication(applicationID uint) error {
|
||||
ret := _m.Called(applicationID)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
if rf, ok := ret.Get(0).(func(uint) error); ok {
|
||||
r0 = rf(applicationID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
|
|
@ -66,11 +66,11 @@ func (_m *MockMessageDatabase) DeleteMessagesByUser(userID uint) error {
|
|||
}
|
||||
|
||||
// GetApplicationByID provides a mock function with given fields: id
|
||||
func (_m *MockMessageDatabase) GetApplicationByID(id string) *model.Application {
|
||||
func (_m *MockMessageDatabase) GetApplicationByID(id uint) *model.Application {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 *model.Application
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Application); ok {
|
||||
if rf, ok := ret.Get(0).(func(uint) *model.Application); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
|
|
@ -81,6 +81,22 @@ func (_m *MockMessageDatabase) GetApplicationByID(id string) *model.Application
|
|||
return r0
|
||||
}
|
||||
|
||||
// GetApplicationByToken provides a mock function with given fields: token
|
||||
func (_m *MockMessageDatabase) GetApplicationByToken(token string) *model.Application {
|
||||
ret := _m.Called(token)
|
||||
|
||||
var r0 *model.Application
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Application); ok {
|
||||
r0 = rf(token)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Application)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetMessageByID provides a mock function with given fields: id
|
||||
func (_m *MockMessageDatabase) GetMessageByID(id uint) *model.Message {
|
||||
ret := _m.Called(id)
|
||||
|
|
@ -97,13 +113,13 @@ func (_m *MockMessageDatabase) GetMessageByID(id uint) *model.Message {
|
|||
return r0
|
||||
}
|
||||
|
||||
// GetMessagesByApplication provides a mock function with given fields: tokenID
|
||||
func (_m *MockMessageDatabase) GetMessagesByApplication(tokenID string) []*model.Message {
|
||||
ret := _m.Called(tokenID)
|
||||
// GetMessagesByApplication provides a mock function with given fields: id
|
||||
func (_m *MockMessageDatabase) GetMessagesByApplication(id uint) []*model.Message {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 []*model.Message
|
||||
if rf, ok := ret.Get(0).(func(string) []*model.Message); ok {
|
||||
r0 = rf(tokenID)
|
||||
if rf, ok := ret.Get(0).(func(uint) []*model.Message); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Message)
|
||||
|
|
|
|||
Loading…
Reference in New Issue