package main import ( "bytes" "context" "encoding/json" "errors" "fmt" "net/http" "strings" "git.cin.su/m/Assistant/contracts/authority" ) var ErrControlPlaneUnavailable = errors.New("delegated control-plane authority unavailable") type controlPlaneAuthority struct { baseURL string client *http.Client credential func() (string, error) } func (a controlPlaneAuthority) authorize(ctx context.Context, request authority.DelegatedControlPlaneRequest) error { return a.post(ctx, "/v1/internal/control-plane/authorize", request) } func (a controlPlaneAuthority) completed(ctx context.Context, request authority.DelegatedControlPlaneRequest, success bool) { outcome := "FAILED" if success { outcome = "COMPLETED" } _ = a.post(ctx, "/v1/internal/control-plane/completions", authority.DelegatedControlPlaneCompletion{Request: request, Outcome: outcome}) } func (a controlPlaneAuthority) revoke(ctx context.Context, creatorAuthorization string, grantID authority.GrantID) error { request, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimRight(a.baseURL, "/")+"/v1/creator/control-plane/grants/"+string(grantID)+"/revoke", nil) if err != nil { return err } request.Header.Set("Authorization", creatorAuthorization) response, err := a.client.Do(request) if err != nil { return err } defer response.Body.Close() if response.StatusCode != http.StatusNoContent { return fmt.Errorf("delegated grant revoke status %d", response.StatusCode) } return nil } func (a controlPlaneAuthority) post(ctx context.Context, path string, value any) error { credential, err := a.credential() if err != nil || credential == "" { return ErrControlPlaneUnavailable } body, err := json.Marshal(value) if err != nil { return err } request, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimRight(a.baseURL, "/")+path, bytes.NewReader(body)) if err != nil { return err } request.Header.Set("Authorization", "Bearer "+credential) request.Header.Set("Content-Type", "application/json") response, err := a.client.Do(request) if err != nil { return err } defer response.Body.Close() if response.StatusCode < 200 || response.StatusCode >= 300 { return fmt.Errorf("delegated control-plane status %d", response.StatusCode) } return nil }