mirror of
https://gitlab.bertha.cloud/partitio/Nextcloud-Partitio/gonextcloud
synced 2024-11-22 05:56:25 +00:00
#1 Implements Notifications API
This commit is contained in:
parent
4a1bec45bf
commit
75e83977e4
5
Makefile
5
Makefile
@ -5,7 +5,7 @@ GO_FILES := $(shell find . -name '*.go' | grep -v _test.go)
|
|||||||
|
|
||||||
.PHONY: all dep build clean test coverage coverhtml lint
|
.PHONY: all dep build clean test coverage coverhtml lint
|
||||||
|
|
||||||
all: build
|
all: dep lint test race coverage
|
||||||
|
|
||||||
lint: ## Lint the files
|
lint: ## Lint the files
|
||||||
@golint -set_exit_status ${PKG_LIST}
|
@golint -set_exit_status ${PKG_LIST}
|
||||||
@ -28,5 +28,8 @@ dep: ## Get the dependencies
|
|||||||
@mkdir -p vendor
|
@mkdir -p vendor
|
||||||
@govendor add +external
|
@govendor add +external
|
||||||
|
|
||||||
|
push: dep lint test coverage ## Push to git repository
|
||||||
|
@git push origin master
|
||||||
|
|
||||||
help: ## Display this help screen
|
help: ## Display this help screen
|
||||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
@ -478,6 +478,9 @@ func TestUserCreateWithoutPassword(t *testing.T) {
|
|||||||
if err := initClient(); err != nil {
|
if err := initClient(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
if c.version.Major < 14 {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
// Nextcloud does not seems to like recreating a deleted user
|
// Nextcloud does not seems to like recreating a deleted user
|
||||||
err := c.UserCreateWithoutPassword(config.NotExistingUser, config.Email, strings.Title(config.NotExistingUser))
|
err := c.UserCreateWithoutPassword(config.NotExistingUser, config.Email, strings.Title(config.NotExistingUser))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
83
notifications.go
Normal file
83
notifications.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package gonextcloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
req "github.com/levigross/grequests"
|
||||||
|
"gitlab.adphi.fr/partitio/Nextcloud-Partitio/gonextcloud/types"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
//NotificationsList returns all the notifications
|
||||||
|
func (c *Client) NotificationsList() ([]types.Notification, error) {
|
||||||
|
if err := c.notificationsAvailable(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res, err := c.baseRequest(http.MethodGet, routes.notifications, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var r types.NotificationsListResponse
|
||||||
|
res.JSON(&r)
|
||||||
|
return r.Ocs.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Notifications returns the notification corresponding to the id
|
||||||
|
func (c *Client) Notifications(id int) (types.Notification, error) {
|
||||||
|
if err := c.notificationsAvailable(); err != nil {
|
||||||
|
return types.Notification{}, err
|
||||||
|
}
|
||||||
|
res, err := c.baseRequest(http.MethodGet, routes.notifications, nil, strconv.Itoa(id))
|
||||||
|
if err != nil {
|
||||||
|
return types.Notification{}, err
|
||||||
|
}
|
||||||
|
var r types.NotificationResponse
|
||||||
|
res.JSON(&r)
|
||||||
|
return r.Ocs.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//NotificationsDelete deletes the notification corresponding to the id
|
||||||
|
func (c *Client) NotificationsDelete(id int) error {
|
||||||
|
if err := c.notificationsAvailable(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err := c.baseRequest(http.MethodDelete, routes.notifications, nil, strconv.Itoa(id))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//NotificationsDeleteAll deletes all notifications
|
||||||
|
func (c *Client) NotificationsDeleteAll() error {
|
||||||
|
if err := c.notificationsAvailable(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err := c.baseRequest(http.MethodDelete, routes.notifications, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//NotificationsCreate creates a notification (if the user is an admin)
|
||||||
|
func (c *Client) NotificationsCreate(userID, title, message string) error {
|
||||||
|
if err := c.adminNotificationsAvailable(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ro := &req.RequestOptions{
|
||||||
|
Data: map[string]string{
|
||||||
|
"shortMessage": title,
|
||||||
|
"longMessage": message,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err := c.baseRequest(http.MethodPost, routes.adminNotifications, ro, userID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) adminNotificationsAvailable() error {
|
||||||
|
if len(c.capabilities.Notifications.AdminNotifications) == 0 {
|
||||||
|
return errors.New("'admin notifications' not available on this instance")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c *Client) notificationsAvailable() error {
|
||||||
|
if len(c.capabilities.Notifications.OcsEndpoints) == 0 {
|
||||||
|
return errors.New("notifications not available on this instance")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
90
notifications_test.go
Normal file
90
notifications_test.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package gonextcloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
notificationID int
|
||||||
|
createdID int
|
||||||
|
title = "Short Message"
|
||||||
|
message = "Longer notification message"
|
||||||
|
tests = []struct {
|
||||||
|
string
|
||||||
|
test
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"notificationCreate",
|
||||||
|
func(t *testing.T) {
|
||||||
|
err := c.NotificationsCreate(config.Login, title, message)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
"notificationDelete",
|
||||||
|
func(t *testing.T) {
|
||||||
|
// Get created Notification ID
|
||||||
|
ns, err := c.NotificationsList()
|
||||||
|
if err != nil {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
for _, n := range ns {
|
||||||
|
if n.Subject == title {
|
||||||
|
createdID = n.NotificationID
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if createdID == 0 {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
err = c.NotificationsDelete(createdID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNotificationsList(t *testing.T) {
|
||||||
|
c = nil
|
||||||
|
if err := initClient(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := c.notificationsAvailable(); err != nil {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
ns, err := c.NotificationsList()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if len(ns) > 0 {
|
||||||
|
notificationID = ns[0].NotificationID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNotifications(t *testing.T) {
|
||||||
|
if notificationID == 0 {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
c = nil
|
||||||
|
if err := initClient(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := c.notificationsAvailable(); err != nil {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
n, err := c.Notifications(notificationID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable due to very long response time
|
||||||
|
//func TestNotificationsAdmin(t *testing.T) {
|
||||||
|
// c = nil
|
||||||
|
// if err := initClient(); err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
// if err := c.adminNotificationsAvailable(); err != nil {
|
||||||
|
// t.SkipNow()
|
||||||
|
// }
|
||||||
|
// for _, test := range tests {
|
||||||
|
// t.Run(test.string, test.test)
|
||||||
|
// }
|
||||||
|
//}
|
@ -12,6 +12,8 @@ type Routes struct {
|
|||||||
shares *url.URL
|
shares *url.URL
|
||||||
groupfolders *url.URL
|
groupfolders *url.URL
|
||||||
appsConfig *url.URL
|
appsConfig *url.URL
|
||||||
|
notifications *url.URL
|
||||||
|
adminNotifications *url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
const badRequest = 998
|
const badRequest = 998
|
||||||
@ -25,7 +27,9 @@ var (
|
|||||||
apps: &url.URL{Path: apiPath.Path + "/cloud/apps"},
|
apps: &url.URL{Path: apiPath.Path + "/cloud/apps"},
|
||||||
monitor: &url.URL{Path: apiPath.Path + "/apps/serverinfo/api/v1/info"},
|
monitor: &url.URL{Path: apiPath.Path + "/apps/serverinfo/api/v1/info"},
|
||||||
shares: &url.URL{Path: apiPath.Path + "/apps/files_sharing/api/v1/shares"},
|
shares: &url.URL{Path: apiPath.Path + "/apps/files_sharing/api/v1/shares"},
|
||||||
groupfolders: &url.URL{Path: "apps/groupfolders/folders"},
|
groupfolders: &url.URL{Path: "/apps/groupfolders/folders"},
|
||||||
appsConfig: &url.URL{Path: apiPath.Path + "/apps/provisioning_api/api/v1/config/apps"},
|
appsConfig: &url.URL{Path: apiPath.Path + "/apps/provisioning_api/api/v1/config/apps"},
|
||||||
|
notifications: &url.URL{Path: apiPath.Path + "/apps/notifications/api/v2/notifications"},
|
||||||
|
adminNotifications: &url.URL{Path: apiPath.Path + "/apps/admin_notifications/api/v2/notifications"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -12,6 +12,17 @@ type Capabilities struct {
|
|||||||
Activity struct {
|
Activity struct {
|
||||||
Apiv2 []string `json:"apiv2"`
|
Apiv2 []string `json:"apiv2"`
|
||||||
} `json:"activity"`
|
} `json:"activity"`
|
||||||
|
Ocm struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
APIVersion string `json:"apiVersion"`
|
||||||
|
EndPoint string `json:"endPoint"`
|
||||||
|
ShareTypes []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Protocols struct {
|
||||||
|
Webdav string `json:"webdav"`
|
||||||
|
} `json:"protocols"`
|
||||||
|
} `json:"shareTypes"`
|
||||||
|
} `json:"ocm"`
|
||||||
Dav struct {
|
Dav struct {
|
||||||
Chunking string `json:"chunking"`
|
Chunking string `json:"chunking"`
|
||||||
} `json:"dav"`
|
} `json:"dav"`
|
||||||
@ -43,6 +54,7 @@ type Capabilities struct {
|
|||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
} `json:"expire_date"`
|
} `json:"expire_date"`
|
||||||
} `json:"group"`
|
} `json:"group"`
|
||||||
|
DefaultPermissions int `json:"default_permissions"`
|
||||||
Federation struct {
|
Federation struct {
|
||||||
Outgoing bool `json:"outgoing"`
|
Outgoing bool `json:"outgoing"`
|
||||||
Incoming bool `json:"incoming"`
|
Incoming bool `json:"incoming"`
|
||||||
@ -66,6 +78,7 @@ type Capabilities struct {
|
|||||||
Notifications struct {
|
Notifications struct {
|
||||||
OcsEndpoints []string `json:"ocs-endpoints"`
|
OcsEndpoints []string `json:"ocs-endpoints"`
|
||||||
Push []string `json:"push"`
|
Push []string `json:"push"`
|
||||||
|
AdminNotifications []string `json:"admin-notifications"`
|
||||||
} `json:"notifications"`
|
} `json:"notifications"`
|
||||||
PasswordPolicy struct {
|
PasswordPolicy struct {
|
||||||
MinLength int `json:"minLength"`
|
MinLength int `json:"minLength"`
|
||||||
@ -92,4 +105,9 @@ type Capabilities struct {
|
|||||||
Undelete bool `json:"undelete"`
|
Undelete bool `json:"undelete"`
|
||||||
Versioning bool `json:"versioning"`
|
Versioning bool `json:"versioning"`
|
||||||
} `json:"files"`
|
} `json:"files"`
|
||||||
|
Registration struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
APIRoot string `json:"apiRoot"`
|
||||||
|
APILevel string `json:"apiLevel"`
|
||||||
|
} `json:"registration"`
|
||||||
}
|
}
|
||||||
|
21
types/notification.go
Normal file
21
types/notification.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Notification struct {
|
||||||
|
NotificationID int `json:"notification_id"`
|
||||||
|
App string `json:"app"`
|
||||||
|
User string `json:"user"`
|
||||||
|
Datetime time.Time `json:"datetime"`
|
||||||
|
ObjectType string `json:"object_type"`
|
||||||
|
ObjectID string `json:"object_id"`
|
||||||
|
Subject string `json:"subject"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Link string `json:"link"`
|
||||||
|
SubjectRich string `json:"subjectRich"`
|
||||||
|
SubjectRichParameters []interface{} `json:"subjectRichParameters"`
|
||||||
|
MessageRich string `json:"messageRich"`
|
||||||
|
MessageRichParameters []interface{} `json:"messageRichParameters"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
Actions []interface{} `json:"actions"`
|
||||||
|
}
|
@ -168,3 +168,17 @@ type GroupFoldersResponse struct {
|
|||||||
Data GroupFolderBadFormatGroups `json:"data"`
|
Data GroupFolderBadFormatGroups `json:"data"`
|
||||||
} `json:"ocs"`
|
} `json:"ocs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NotificationsListResponse struct {
|
||||||
|
Ocs struct {
|
||||||
|
Meta Meta `json:"meta"`
|
||||||
|
Data []Notification `json:"data"`
|
||||||
|
} `json:"ocs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotificationResponse struct {
|
||||||
|
Ocs struct {
|
||||||
|
Meta Meta `json:"meta"`
|
||||||
|
Data Notification `json:"data"`
|
||||||
|
} `json:"ocs"`
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user