ExApps can Send/SendTo a bell for one Recipient and read group membership and directory OCS as the Requesting user, with Access Gate using UserGroups. Co-authored-by: Cursor <cursoragent@cursor.com>
188 lines
5.1 KiB
Go
188 lines
5.1 KiB
Go
package gonexapp_test
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.neitzel.de/konrad/go-nc-exapp"
|
|
)
|
|
|
|
func groupsAuthUser(r *http.Request) string {
|
|
raw := r.Header.Get("AUTHORIZATION-APP-API")
|
|
decoded, err := base64.StdEncoding.DecodeString(raw)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
parts := strings.SplitN(string(decoded), ":", 2)
|
|
if len(parts) < 1 {
|
|
return ""
|
|
}
|
|
return parts[0]
|
|
}
|
|
|
|
func TestGroupsUserGroups(t *testing.T) {
|
|
var gotMethod, gotPath, gotUser string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotMethod = r.Method
|
|
gotPath = r.URL.Path
|
|
gotUser = groupsAuthUser(r)
|
|
_ = json.NewEncoder(w).Encode(map[string]any{
|
|
"ocs": map[string]any{"data": map[string]any{"groups": []string{"dns-ops", "users"}}},
|
|
})
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cred := gonexapp.Credentials{
|
|
BaseURL: srv.URL, AppID: "app", AppVersion: "0.1.0", AAVersion: "1.0.0", AppSecret: "s", UserID: "admin",
|
|
}
|
|
g := gonexapp.NewGroups(cred)
|
|
g.Client = srv.Client()
|
|
g.OCS.Client = srv.Client()
|
|
|
|
got, err := g.UserGroups("alice")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotMethod != http.MethodGet {
|
|
t.Fatalf("method=%q", gotMethod)
|
|
}
|
|
if !strings.Contains(gotPath, "/cloud/users/alice/groups") {
|
|
t.Fatalf("path=%q", gotPath)
|
|
}
|
|
if gotUser != "alice" {
|
|
t.Fatalf("auth user=%q want alice", gotUser)
|
|
}
|
|
if len(got) != 2 || got[0] != "dns-ops" || got[1] != "users" {
|
|
t.Fatalf("got %#v", got)
|
|
}
|
|
}
|
|
|
|
func TestGroupsGroupMembers(t *testing.T) {
|
|
var gotMethod, gotPath, gotUser string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotMethod = r.Method
|
|
gotPath = r.URL.Path
|
|
gotUser = groupsAuthUser(r)
|
|
_ = json.NewEncoder(w).Encode(map[string]any{
|
|
"ocs": map[string]any{"data": map[string]any{"users": []string{"alice", "bob"}}},
|
|
})
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cred := gonexapp.Credentials{
|
|
BaseURL: srv.URL, AppID: "app", AppVersion: "0.1.0", AAVersion: "1.0.0", AppSecret: "s", UserID: "admin",
|
|
}
|
|
g := gonexapp.NewGroups(cred)
|
|
g.Client = srv.Client()
|
|
g.OCS.Client = srv.Client()
|
|
|
|
got, err := g.GroupMembers("CheckDNS")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotMethod != http.MethodGet {
|
|
t.Fatalf("method=%q", gotMethod)
|
|
}
|
|
if !strings.Contains(gotPath, "/cloud/groups/CheckDNS") {
|
|
t.Fatalf("path=%q", gotPath)
|
|
}
|
|
if gotUser != "admin" {
|
|
t.Fatalf("auth user=%q want admin", gotUser)
|
|
}
|
|
if len(got) != 2 || got[0] != "alice" || got[1] != "bob" {
|
|
t.Fatalf("got %#v", got)
|
|
}
|
|
}
|
|
|
|
func TestGroupsListGroups(t *testing.T) {
|
|
var gotMethod, gotPath, gotUser string
|
|
var gotQuery map[string][]string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotMethod = r.Method
|
|
gotPath = r.URL.Path
|
|
gotUser = groupsAuthUser(r)
|
|
gotQuery = r.URL.Query()
|
|
_ = json.NewEncoder(w).Encode(map[string]any{
|
|
"ocs": map[string]any{"data": map[string]any{"groups": []string{"CheckDNS", "users"}}},
|
|
})
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cred := gonexapp.Credentials{
|
|
BaseURL: srv.URL, AppID: "app", AppVersion: "0.1.0", AAVersion: "1.0.0", AppSecret: "s", UserID: "admin",
|
|
}
|
|
g := gonexapp.NewGroups(cred)
|
|
g.Client = srv.Client()
|
|
g.OCS.Client = srv.Client()
|
|
|
|
got, err := g.ListGroups()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotMethod != http.MethodGet {
|
|
t.Fatalf("method=%q", gotMethod)
|
|
}
|
|
if gotPath != "/ocs/v2.php/cloud/groups" {
|
|
if !strings.Contains(gotPath, "/cloud/groups") || strings.Contains(gotPath, "/cloud/groups/") {
|
|
t.Fatalf("path=%q", gotPath)
|
|
}
|
|
}
|
|
if gotUser != "admin" {
|
|
t.Fatalf("auth user=%q want admin", gotUser)
|
|
}
|
|
if _, ok := gotQuery["search"]; ok {
|
|
t.Fatalf("unexpected search query: %v", gotQuery["search"])
|
|
}
|
|
if _, ok := gotQuery["limit"]; ok {
|
|
t.Fatalf("unexpected limit query: %v", gotQuery["limit"])
|
|
}
|
|
if _, ok := gotQuery["offset"]; ok {
|
|
t.Fatalf("unexpected offset query: %v", gotQuery["offset"])
|
|
}
|
|
if len(got) != 2 || got[0] != "CheckDNS" || got[1] != "users" {
|
|
t.Fatalf("got %#v", got)
|
|
}
|
|
}
|
|
|
|
func TestGroupsGroupMembersForbidden(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "forbidden", http.StatusForbidden)
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cred := gonexapp.Credentials{
|
|
BaseURL: srv.URL, AppID: "app", AppVersion: "0.1.0", AAVersion: "1.0.0", AppSecret: "s", UserID: "alice",
|
|
}
|
|
g := gonexapp.NewGroups(cred)
|
|
g.Client = srv.Client()
|
|
g.OCS.Client = srv.Client()
|
|
|
|
_, err := g.GroupMembers("CheckDNS")
|
|
if err == nil || !strings.Contains(err.Error(), "403") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGroupsListGroupsForbidden(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "forbidden", http.StatusForbidden)
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cred := gonexapp.Credentials{
|
|
BaseURL: srv.URL, AppID: "app", AppVersion: "0.1.0", AAVersion: "1.0.0", AppSecret: "s", UserID: "alice",
|
|
}
|
|
g := gonexapp.NewGroups(cred)
|
|
g.Client = srv.Client()
|
|
g.OCS.Client = srv.Client()
|
|
|
|
_, err := g.ListGroups()
|
|
if err == nil || !strings.Contains(err.Error(), "403") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
}
|