github.com/supabase/cli@v1.168.1/internal/sso/update/update.go (about)

     1  package update
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"os"
     7  
     8  	"github.com/go-errors/errors"
     9  	"github.com/spf13/afero"
    10  	"github.com/supabase/cli/internal/sso/internal/render"
    11  	"github.com/supabase/cli/internal/sso/internal/saml"
    12  	"github.com/supabase/cli/internal/utils"
    13  	"github.com/supabase/cli/pkg/api"
    14  )
    15  
    16  var Fs = afero.NewOsFs()
    17  
    18  type RunParams struct {
    19  	ProjectRef string
    20  	ProviderID string
    21  	Format     string
    22  
    23  	MetadataFile      string
    24  	MetadataURL       string
    25  	SkipURLValidation bool
    26  	AttributeMapping  string
    27  
    28  	Domains       []string
    29  	AddDomains    []string
    30  	RemoveDomains []string
    31  }
    32  
    33  func Run(ctx context.Context, params RunParams) error {
    34  	getResp, err := utils.GetSupabase().GetProviderByIdWithResponse(ctx, params.ProjectRef, params.ProviderID)
    35  	if err != nil {
    36  		return errors.Errorf("failed to get sso provider: %w", err)
    37  	}
    38  
    39  	if getResp.JSON200 == nil {
    40  		if getResp.StatusCode() == http.StatusNotFound {
    41  			return errors.Errorf("An identity provider with ID %q could not be found.", params.ProviderID)
    42  		}
    43  
    44  		return errors.New("unexpected error fetching identity provider: " + string(getResp.Body))
    45  	}
    46  
    47  	var body api.UpdateProviderByIdJSONRequestBody
    48  
    49  	if params.MetadataFile != "" {
    50  		data, err := saml.ReadMetadataFile(Fs, params.MetadataFile)
    51  		if err != nil {
    52  			return err
    53  		}
    54  
    55  		body.MetadataXml = &data
    56  	} else if params.MetadataURL != "" {
    57  		if !params.SkipURLValidation {
    58  			if err := saml.ValidateMetadataURL(ctx, params.MetadataURL); err != nil {
    59  				return errors.Errorf("%w Use --skip-url-validation to suppress this error.", err)
    60  			}
    61  		}
    62  
    63  		body.MetadataUrl = &params.MetadataURL
    64  	}
    65  
    66  	if params.AttributeMapping != "" {
    67  		data, err := saml.ReadAttributeMappingFile(Fs, params.AttributeMapping)
    68  		if err != nil {
    69  			return err
    70  		}
    71  
    72  		body.AttributeMapping = data
    73  	}
    74  
    75  	if len(params.Domains) != 0 {
    76  		body.Domains = &params.Domains
    77  	} else if params.AddDomains != nil || params.RemoveDomains != nil {
    78  		domainsSet := make(map[string]bool)
    79  
    80  		if getResp.JSON200.Domains != nil {
    81  			for _, domain := range *getResp.JSON200.Domains {
    82  				if domain.Domain != nil {
    83  					domainsSet[*domain.Domain] = true
    84  				}
    85  			}
    86  		}
    87  
    88  		for _, rmDomain := range params.RemoveDomains {
    89  			delete(domainsSet, rmDomain)
    90  		}
    91  
    92  		for _, addDomain := range params.AddDomains {
    93  			domainsSet[addDomain] = true
    94  		}
    95  
    96  		domains := make([]string, 0)
    97  		for domain := range domainsSet {
    98  			domains = append(domains, domain)
    99  		}
   100  
   101  		body.Domains = &domains
   102  	}
   103  
   104  	putResp, err := utils.GetSupabase().UpdateProviderByIdWithResponse(ctx, params.ProjectRef, params.ProviderID, body)
   105  	if err != nil {
   106  		return errors.Errorf("failed to update sso provider: %w", err)
   107  	}
   108  
   109  	if putResp.JSON200 == nil {
   110  		return errors.New("unexpected error fetching identity provider: " + string(putResp.Body))
   111  	}
   112  
   113  	switch params.Format {
   114  	case utils.OutputPretty:
   115  		return render.SingleMarkdown(api.Provider{
   116  			Id:        putResp.JSON200.Id,
   117  			Saml:      putResp.JSON200.Saml,
   118  			Domains:   putResp.JSON200.Domains,
   119  			CreatedAt: putResp.JSON200.CreatedAt,
   120  			UpdatedAt: putResp.JSON200.UpdatedAt,
   121  		})
   122  
   123  	default:
   124  		return utils.EncodeOutput(params.Format, os.Stdout, putResp.JSON200)
   125  	}
   126  }