Files
go-nc-exapp/groups_test.go
Konrad NeitzelandCursor fc2f9f63c2 Add AppAPI Notifications and Users and Groups reads.
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>
2026-08-28 14:44:42 +02:00

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)
}
}