package permissions import ( "context" "fmt" "net/http" "go.infratographer.com/x/gidx" ) // RoleAssign is the role assignment request body. type RoleAssign struct { SubjectID string `json:"subject_id"` } // RoleAssignResponse is the response from a role assignment. type RoleAssignResponse struct { Success bool `json:"success"` } // roleAssignmentData is the response from listing a role assignment type roleAssignmentData struct { Data []struct { SubjectID string `json:"subject_id"` } `json:"data"` } // AssignRole assigns the provided member ID to the given role ID. func (c *Client) AssignRole(ctx context.Context, roleID gidx.PrefixedID, memberID gidx.PrefixedID) error { path := fmt.Sprintf("/api/v1/roles/%s/assignments", roleID.String()) body, err := encodeJSON(RoleAssign{ SubjectID: memberID.String(), }) if err != nil { return err } var response RoleAssignResponse if _, err = c.DoRequest(ctx, http.MethodPost, path, body, &response); err != nil { return err } if !response.Success { return ErrAssignmentFailed } return nil } // UnassignRole removes the provided member ID from the given role ID. func (c *Client) UnassignRole(ctx context.Context, roleID gidx.PrefixedID, memberID gidx.PrefixedID) error { path := fmt.Sprintf("/api/v1/roles/%s/assignments", roleID.String()) body, err := encodeJSON(RoleAssign{ SubjectID: memberID.String(), }) if err != nil { return err } var response RoleAssignResponse if _, err = c.DoRequest(ctx, http.MethodDelete, path, body, &response); err != nil { return err } if !response.Success { return ErrUnassignmentFailed } return nil } // ListRoleAssignments lists all assignments for the given role. func (c *Client) ListRoleAssignments(ctx context.Context, roleID gidx.PrefixedID) ([]gidx.PrefixedID, error) { path := fmt.Sprintf("/api/v1/roles/%s/assignments", roleID.String()) var response roleAssignmentData if _, err := c.DoRequest(ctx, http.MethodGet, path, nil, &response); err != nil { return nil, err } assignments := make([]gidx.PrefixedID, len(response.Data)) for i, assignment := range response.Data { id, err := gidx.Parse(assignment.SubjectID) if err != nil { return nil, fmt.Errorf("%w: failed parsing id %s", err, assignment.SubjectID) } assignments[i] = id } return assignments, nil } // RoleHasAssignment gets the assignments for the given role and check for the provided member id. func (c *Client) RoleHasAssignment(ctx context.Context, roleID gidx.PrefixedID, memberID gidx.PrefixedID) (bool, error) { assignments, err := c.ListRoleAssignments(ctx, roleID) if err != nil { return false, err } for _, assignment := range assignments { if assignment == memberID { return true, nil } } return false, nil }