package internal import ( "encoding/xml" "fmt" "strings" "testing" ) func decodePropInsideMultiStatus(data []byte, v interface{}) error { var ms MultiStatus err := xml.Unmarshal(data, &ms) if err != nil { return err } if len(ms.Responses) != 1 { return fmt.Errorf("expected 1 , got %d", len(ms.Responses)) } ps := ms.Responses[0].PropStats if len(ps) != 1 { return fmt.Errorf("expected 1 , got %d", len(ps)) } return ps[0].Prop.Decode(v) } func checkSupportedPrivilege(t *testing.T, sp SupportedPrivilege, privilege xml.Name, abstract bool, description string, children int) { t.Helper() if !sp.Privilege.Is(privilege) { t.Errorf("expected %s, got %v", privilege, sp.Privilege.Raw) } if abstract { if sp.Abstract == nil { t.Errorf("missing expected ") } } else { if sp.Abstract != nil { t.Errorf("unexpected ") } } if strings.TrimSpace(sp.Description.Text) != description { t.Errorf("expected description %q, got %q", description, strings.TrimSpace(sp.Description.Text)) } if strings.TrimSpace(sp.Description.Lang) != "en" { t.Errorf("expected lang %q, got %q", "en", sp.Description.Lang) } if len(sp.SupportedPrivilege) != children { t.Fatalf("expected %d , got %d", children, len(sp.SupportedPrivilege)) } } func TestACLMarshalling(t *testing.T) { /* rfc3744#section-5.1.1 */ t.Run("owner", func(t *testing.T) { var owner Owner err := decodePropInsideMultiStatus([]byte(` http://www.example.com/papers/ http://www.example.com/acl/users/gstein HTTP/1.1 200 OK `), &owner) if err != nil { t.Error(err) } if owner.Href.String() != "http://www.example.com/acl/users/gstein" { t.Fatalf("expected http://www.example.com/acl/users/gstein, got %s", owner.Href.String()) } }) /* rfc3744#section-5.3.1 */ t.Run("supported-privilege-set", func(t *testing.T) { var sps SupportedPrivilegeSet err := decodePropInsideMultiStatus([]byte(` http://www.example.com/papers/ Any operation Read any object Read ACL Read current user privilege set property Write any object Write ACL Write properties Write resource content Unlock resource HTTP/1.1 200 OK `), &sps) if err != nil { t.Error(err) } if len(sps.SupportedPrivilege) != 1 { t.Fatalf("expected 1 , got %d", len(sps.SupportedPrivilege)) } sp := sps.SupportedPrivilege[0] checkSupportedPrivilege(t, sp, All, true, "Any operation", 3) checkSupportedPrivilege(t, sp.SupportedPrivilege[0], Read, false, "Read any object", 2) checkSupportedPrivilege(t, sp.SupportedPrivilege[1], Write, false, "Write any object", 3) checkSupportedPrivilege(t, sp.SupportedPrivilege[2], Unlock, false, "Unlock resource", 0) checkSupportedPrivilege(t, sp.SupportedPrivilege[0].SupportedPrivilege[0], ReadACL, true, "Read ACL", 0) checkSupportedPrivilege(t, sp.SupportedPrivilege[0].SupportedPrivilege[1], ReadCurrentUserPrivilegeSet, true, "Read current user privilege set property", 0) checkSupportedPrivilege(t, sp.SupportedPrivilege[1].SupportedPrivilege[0], WriteACL, true, "Write ACL", 0) checkSupportedPrivilege(t, sp.SupportedPrivilege[1].SupportedPrivilege[1], WriteProperties, false, "Write properties", 0) checkSupportedPrivilege(t, sp.SupportedPrivilege[1].SupportedPrivilege[2], WriteContent, false, "Write resource content", 0) sp = SupportedPrivilege{ Privilege: NewPrivilege(All), Abstract: &struct{}{}, Description: Description{Text: "all"}, } buf, err := xml.Marshal(sp) if err != nil { t.Error(err) } if want := "all"; string(buf) != want { t.Errorf("expected %q, got %q", want, buf) } sp = SupportedPrivilege{ Privilege: NewPrivilege(Read), Abstract: nil, Description: Description{Text: "read"}, } buf, err = xml.Marshal(sp) if err != nil { t.Error(err) } if want := "read"; string(buf) != want { t.Errorf("expected %q, got %q", want, buf) } }) /* rfc3744#section-5.4.1 */ t.Run("current-user-privilege-set", func(t *testing.T) { var cups CurrentUserPrivilegeSet err := decodePropInsideMultiStatus([]byte(` http://www.example.com/papers/ HTTP/1.1 200 OK `), &cups) if err != nil { t.Error(err) } if len(cups.Privilege) != 1 { t.Fatalf("expected 1 , got %d", len(cups.Privilege)) } if !cups.Privilege[0].Is(Read) { t.Fatalf("expected , got %v", cups.Privilege[0].Raw) } }) /* rfc3744#section-5.5.5 */ t.Run("acl", func(t *testing.T) { var acl ACL err := decodePropInsideMultiStatus([]byte(` http://www.example.com/papers/ http://www.example.com/acl/groups/maintainers HTTP/1.1 200 OK `), &acl) if err != nil { t.Error(err) } if len(acl.ACE) != 2 { t.Fatalf("expected 2 , got %d", len(acl.ACE)) } { ace := acl.ACE[0] principalName, ok := ace.Principal.Raw.XMLName() if want := (xml.Name{"DAV:", "href"}); !ok || principalName != want { t.Fatalf("expected %s, got %s", want, principalName) } var href Href err = ace.Principal.Raw.Decode(&href) if err != nil { t.Error(err) } if want := "http://www.example.com/acl/groups/maintainers"; href.String() != want { t.Fatalf("expected %s, got %s", want, href.String()) } if len(ace.Grant.Privilege) != 1 { t.Fatalf("expected 1 , got %d", len(ace.Grant.Privilege)) } if !ace.Grant.Privilege[0].Is(Write) { t.Fatalf("expected , got %v", ace.Grant.Privilege[0].Raw) } } { ace := acl.ACE[1] principalName, ok := ace.Principal.Raw.XMLName() if want := (xml.Name{"DAV:", "all"}); !ok || principalName != want { t.Fatalf("expected %s, got %s", want, principalName) } if len(ace.Grant.Privilege) != 1 { t.Fatalf("expected 1 , got %d", len(ace.Grant.Privilege)) } if !ace.Grant.Privilege[0].Is(Read) { t.Fatalf("expected , got %v", ace.Grant.Privilege[0].Raw) } } var ace ACE ace.Principal.Raw = NewRawXMLElement(xml.Name{"DAV:", "authenticated"}, nil, nil) ace.Grant = &Grant{ Privilege: []Privilege{ NewPrivilege(Read), }, } buf, err := xml.Marshal(ace) if err != nil { t.Error(err) } if want := ""; string(buf) != want { t.Errorf("expected %q, got %q", want, buf) } }) }