# Add auth provider to gitsync client

`ff29a6a`→[main](/content/gh/entireio/git-sync/commits/main/index.html)·

## Sessions

ca76acb396e8View transcript

## Changes

3

- pkg/gitsync

- Mclient.go+47/-15
  - Mclient_test.go+33/-6
  - Mtypes.go+31/-8

```go
// Options configures a Client. It is intentionally small in the first public cut.
type Options struct {
	HTTPClient *http.Client
	Auth       AuthProvider
}

// Client provides the public orchestration API for git-sync.
type Client struct {
	httpClient *http.Client
	auth       AuthProvider
}

// New constructs a new Client.
func New(opts Options) *Client {
	return &Client{httpClient: opts.HTTPClient}
	return &Client{httpClient: opts.HTTPClient, auth: opts.Auth}
}

// Probe inspects a source remote and optional target remote.
func buildProbeConfig(req ProbeRequest) syncer.Config {
func (c *Client) buildProbeConfig(ctx context.Context, req ProbeRequest) (syncer.Config, error) {
	sourceAuth, err := c.authFor(ctx, req.Source, SourceRole)
	if err != nil {
		return syncer.Config{}, err
	}
	cfg := syncer.Config{
		Source:       syncer.Endpoint{URL: req.Source.URL, Username: req.SourceAuth.Username, Token: req.SourceAuth.Token, BearerToken: req.SourceAuth.BearerToken, SkipTLSVerify: req.SourceAuth.SkipTLSVerify},
		HTTPClient:   c.httpClient,
		IncludeTags:  req.IncludeTags,
		ShowStats:    req.CollectStats,
		ProtocolMode: string(req.Protocol),
	}
	if req.Target != nil {
		cfg.Target = syncer.Endpoint{URL: req.Target.URL, Username: req.TargetAuth.Username, Token: req.TargetAuth.Token, BearerToken: req.TargetAuth.BearerToken, SkipTLSVerify: req.TargetAuth.SkipTLSVerify}
		targetAuth, err := c.authFor(ctx, *req.Target, TargetRole)
		if err != nil {
			return syncer.Config{}, err
		}
		cfg.Target = syncer.Endpoint{URL: req.Target.URL, Username: targetAuth.Username, Token: targetAuth.Token, BearerToken: targetAuth.BearerToken, SkipTLSVerify: targetAuth.SkipTLSVerify}
	}
	return cfg
}

func (c *Client) buildSyncConfig(source Endpoint, sourceAuth EndpointAuth, target Endpoint, targetAuth EndpointAuth, scope RefScope, policy SyncPolicy, collectStats, dryRun bool) syncer.Config {

}

func TestBuildSyncConfigUsesDefaultProtocolAndMaterializedLimit(t *testing.T) {
	cfg := New(Options{}).buildSyncConfig(
		ctx, err := New(Options{Auth: StaticAuthProvider{
			Source: EndpointAuth{Token: "src"},
			Target: EndpointAuth{Token: "dst"},
		}}).buildSyncConfig(
		context.Background(),
		Endpoint{URL: "https://source.example/repo.git"},
		EndpointAuth{Token: "src"},
		Endpoint{URL: "https://target.example/repo.git"},
		EndpointAuth{Token: "dst"},
		RefScope{Branches: []string{"main"}},
		SyncPolicy{},
		true,
		false,
	)
	if err != nil {
		t.Fatalf("buildSyncConfig: %v", err)
	}

if cfg.ProtocolMode != string(ProtocolAuto) {
		t.Fatalf("protocol mode = %q, want %q", cfg.ProtocolMode, ProtocolAuto)
	}
}

func TestClientCarriesHTTPClientIntoSyncerConfig(t *testing.T) {
	base := &http.Client{}
	cfg := New(Options{HTTPClient: base}).buildSyncConfig(
		context.Background(),
		Endpoint{URL: "https://source.example/repo.git"},
		EndpointAuth{},
		Endpoint{URL: "https://target.example/repo.git"},
		EndpointAuth{},
		RefScope{},
		SyncPolicy{},
		false,
		false,
	)
	if err != nil {
		t.Fatalf("buildSyncConfig: %v", err)
	}
	if cfg.HTTPClient != base {
		t.Fatalf("http client = %p, want %p", cfg.HTTPClient, base)
	}
}

// EndpointAuth carries explicit per-request auth and TLS settings.
type EndpointAuth struct {
	Username      string
	Token         string
	SkipTLSVerify bool
}

// ProbeRequest inspects source refs and optional target capabilities.
type ProbeRequest struct {
	Source       Endpoint
	SourceAuth   EndpointAuth
	Target       *Endpoint
	TargetAuth   EndpointAuth
	IncludeTags  bool
	Protocol     ProtocolMode
	CollectStats bool
}

// SyncRequest executes a sync between two remotes.
type SyncRequest struct {
	Source       Endpoint
	SourceAuth   EndpointAuth
	Target       Endpoint
	TargetAuth   EndpointAuth
	Scope        RefScope
	Policy       SyncPolicy
	CollectStats bool
}
```
