diff --git a/scm/driver/gitea/org.go b/scm/driver/gitea/org.go index c7c7efc03..6ca8ec7ea 100644 --- a/scm/driver/gitea/org.go +++ b/scm/driver/gitea/org.go @@ -23,7 +23,13 @@ func (s *organizationService) Find(ctx context.Context, name string) (*scm.Organ } func (s *organizationService) FindMembership(ctx context.Context, name, username string) (*scm.Membership, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + membership := new(membership) + membership.Active = s.checkMembership(ctx, name, username) + out := new(permissions) + path := fmt.Sprintf("api/v1/users/%s/orgs/%s/permissions", username, name) + res, err := s.client.do(ctx, "GET", path, nil, out) + membership.Permissions = out + return convertMembership(membership), res, err } func (s *organizationService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Organization, *scm.Response, error) { @@ -33,6 +39,18 @@ func (s *organizationService) List(ctx context.Context, opts scm.ListOptions) ([ return convertOrgList(out), res, err } +type permissions struct { + IsOwner bool `json:"is_owner"` + IsAdmin bool `json:"is_admin"` + CanWrite bool `json:"can_write"` + CanRead bool `json:"can_read"` + CanCreateRepository bool `json:"can_create_repository"` +} +type membership struct { + Permissions *permissions + Active bool +} + // // native data structures // @@ -60,3 +78,27 @@ func convertOrg(from *org) *scm.Organization { Avatar: from.Avatar, } } + +func (s *organizationService) checkMembership(ctx context.Context, name, username string) bool { + path := fmt.Sprintf("api/v1/orgs/%s/members/%s", name, username) + res, err := s.client.do(ctx, "GET", path, nil, nil) + if err != nil { + return false + } + return res.Status == 204 +} + +func convertMembership(from *membership) *scm.Membership { + to := new(scm.Membership) + to.Active = from.Active + isAdmin := from.Permissions.IsAdmin + isMember := from.Permissions.CanRead || from.Permissions.CanWrite || from.Permissions.CanCreateRepository + if isAdmin { + to.Role = scm.RoleAdmin + } else if isMember { + to.Role = scm.RoleMember + } else { + to.Role = scm.RoleUndefined + } + return to +} diff --git a/scm/driver/gitea/org_test.go b/scm/driver/gitea/org_test.go index 90a0a193c..ceaba401b 100644 --- a/scm/driver/gitea/org_test.go +++ b/scm/driver/gitea/org_test.go @@ -42,10 +42,31 @@ func TestOrgFind(t *testing.T) { } func TestOrganizationFindMembership(t *testing.T) { + defer gock.Off() + + gock.New("https://try.gitea.io"). + Get("/api/v1/orgs/gogits/members/jcitizen"). + Reply(204) + + gock.New("https://try.gitea.io"). + Get("/api/v1/users/jcitizen/orgs/gogits/permissions"). + Reply(200). + Type("application/json"). + File("testdata/permissions.json") + client, _ := New("https://try.gitea.io") - _, _, err := client.Organizations.FindMembership(context.Background(), "gogits", "jcitizen") - if err != scm.ErrNotSupported { - t.Errorf("Expect Not Supported error") + got, _, err := client.Organizations.FindMembership(context.Background(), "gogits", "jcitizen") + if err != nil { + t.Error(err) + } + + want := new(scm.Membership) + raw, _ := ioutil.ReadFile("testdata/membership.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) } } diff --git a/scm/driver/gitea/testdata/membership.json.golden b/scm/driver/gitea/testdata/membership.json.golden new file mode 100644 index 000000000..96ec5685e --- /dev/null +++ b/scm/driver/gitea/testdata/membership.json.golden @@ -0,0 +1,4 @@ +{ + "Active": true, + "Role": 2 +} \ No newline at end of file diff --git a/scm/driver/gitea/testdata/permissions.json b/scm/driver/gitea/testdata/permissions.json new file mode 100644 index 000000000..77e2cff85 --- /dev/null +++ b/scm/driver/gitea/testdata/permissions.json @@ -0,0 +1,7 @@ +{ + "is_owner": true, + "is_admin": true, + "can_write": true, + "can_read": true, + "can_create_repository": true +}