Skip to content

Commit

Permalink
updated to add token path flag and remove idToken function magic
Browse files Browse the repository at this point in the history
Signed-off-by: chaosinthecrd <[email protected]>
  • Loading branch information
ChaosInTheCRD committed Dec 7, 2023
1 parent 2c2dc7a commit d9e960f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 52 deletions.
2 changes: 1 addition & 1 deletion hack/test.token
Original file line number Diff line number Diff line change
@@ -1 +1 @@
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJhYmNkMTIzIiwiZXhwaXJ5IjoxNjQ2NjM1NjExMzAxfQ.3Thp81rDFrKXr3WrY1MyMnNK8kKoZBX9lg-JwFznR-M
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb29iYXIiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsIkVtYWlsIjoidGVzdEBpbi10b3RvLmlvIn0.IswtNc6aJL3zAf-lSGvuz7Okf2tBr-I3ulJ_SRUMt0k
52 changes: 32 additions & 20 deletions signer/fulcio/fulcio.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func init() {
),
registry.StringConfigOption(
"token",
"Raw token to use for authentication. The token or a path to the file containing the token is accepted",
"Raw token string to use for authentication to fulcio (cannot be used in conjunction with --fulcio-token-path)",
"",
func(sp signer.SignerProvider, token string) (signer.SignerProvider, error) {
fsp, ok := sp.(FulcioSignerProvider)
Expand All @@ -105,6 +105,20 @@ func init() {
return fsp, nil
},
),
registry.StringConfigOption(
"token-path",
"Path to the file containing a raw token to use for authentication to fulcio (cannot be used in conjunction with --fulcio-token)",
"",
func(sp signer.SignerProvider, tokenPath string) (signer.SignerProvider, error) {
fsp, ok := sp.(FulcioSignerProvider)
if !ok {
return sp, fmt.Errorf("provided signer provider is not a fulcio signer provider")
}

WithTokenPath(tokenPath)(&fsp)
return fsp, nil
},
),
)
}

Expand All @@ -113,6 +127,7 @@ type FulcioSignerProvider struct {
OidcIssuer string
OidcClientID string
Token string
TokenPath string
}

type Option func(*FulcioSignerProvider)
Expand Down Expand Up @@ -141,6 +156,12 @@ func WithToken(tokenOption string) Option {
}
}

func WithTokenPath(tokenPathOption string) Option {
return func(fsp *FulcioSignerProvider) {
fsp.TokenPath = tokenPathOption
}
}

func New(opts ...Option) FulcioSignerProvider {
fsp := FulcioSignerProvider{}
for _, opt := range opts {
Expand Down Expand Up @@ -210,13 +231,18 @@ func (fsp FulcioSignerProvider) Signer(ctx context.Context) (cryptoutil.Signer,
return nil, err
}

case fsp.Token != "":
// reading from file if a path was supplied
raw, err = idToken(fsp.Token)
// we want to fail if both flags used (they're mutually exclusive)
case fsp.TokenPath != "" && fsp.Token != "":
return nil, errors.New("only one of --fulcio-token-path or --fulcio-raw-token can be used")
case fsp.Token != "" && fsp.TokenPath == "":
raw = fsp.Token
case fsp.TokenPath != "" && fsp.Token == "":
f, err := os.ReadFile(fsp.TokenPath)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to read fulcio token from filepath %s: %w", fsp.TokenPath, err)
}

raw = string(f)
case fsp.Token == "" && isatty.IsTerminal(os.Stdin.Fd()):
tok, err := oauthflow.OIDConnect(fsp.OidcIssuer, fsp.OidcClientID, "", "", oauthflow.DefaultIDTokenGetter)
if err != nil {
Expand Down Expand Up @@ -285,7 +311,7 @@ func (fsp FulcioSignerProvider) Signer(ctx context.Context) (cryptoutil.Signer,
func getCert(ctx context.Context, key *rsa.PrivateKey, fc fulciopb.CAClient, token string) (*fulciopb.SigningCertificate, error) {
t, err := jwt.ParseSigned(token)
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to parse jwt token for fulcio: %w", err)
}

var claims struct {
Expand Down Expand Up @@ -407,17 +433,3 @@ func newClient(ctx context.Context, fulcioURL string, fulcioPort int, isInsecure
// Create the Fulcio client
return fulciopb.NewCAClient(conn), nil
}

// idToken tries to parse a string as a token in JWS form. If it fails,
// it treats the string as a path and tries to open the file at that path
func idToken(s string) (string, error) {
// If this is a valid raw token, just return it
// NOTE: could be replaced with https://pkg.go.dev/go.step.sm/crypto/jose in future if features helpful
if _, err := jwt.ParseSigned(s); err == nil {
return s, nil
}

// Otherwise, if this is a path to a token return the contents
c, err := os.ReadFile(s)
return string(c), err
}
50 changes: 19 additions & 31 deletions signer/fulcio/fulcio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,37 +78,6 @@ func TestNewClient(t *testing.T) {
require.NotNil(t, client)
}

func TestIDToken(t *testing.T) {
// test when supplying a raw token, the same token is returned
tok := generateTestToken("[email protected]", "testsubject")
out, err := idToken(tok)
require.NoError(t, err)
require.Equal(t, tok, out)

// test when supplying a path, a valid token is returned
// NOTE: this function could be refactored to accept a fileSystem or io.Reader so reading the file can be mocked,
// but unsure if this is the way we want to go for now
wd, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
rootDir := filepath.Dir(filepath.Dir(wd))
tok = filepath.Join(rootDir, "hack", "test.token")
testTok, err := os.ReadFile(tok)
if err != nil {
t.Fatalf("failed to read test token file: %v", err)
}

out, err = idToken(tok)
require.NoError(t, err)
require.Equal(t, string(testTok), out)

// test that when neither valid token nor a path is supplied, an error is returned
tok = "test"
_, err = idToken(tok)
require.Error(t, err)
}

type dummyCAClientService struct {
client fulciopb.CAClient
server *grpc.Server
Expand Down Expand Up @@ -231,6 +200,25 @@ func TestSigner(t *testing.T) {
_, err = provider.Signer(ctx)
//this should be a tranport err since we cant actually test on 443 which is the default
require.ErrorContains(t, err, "lookup test")

// Test signer with token read from file
// NOTE: this function could be refactored to accept a fileSystem or io.Reader so reading the file can be mocked,
// but unsure if this is the way we want to go for now
wd, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
rootDir := filepath.Dir(filepath.Dir(wd))
tp := filepath.Join(rootDir, "hack", "test.token")

provider = New(WithFulcioURL(fmt.Sprintf("http://%v:%v", hostname, port)), WithTokenPath(tp))
signer, err = provider.Signer(ctx)

Check failure on line 215 in signer/fulcio/fulcio_test.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to signer (ineffassign)
require.NoError(t, err)

// Test signer with both token read from file and raw token
provider = New(WithFulcioURL(fmt.Sprintf("http://%v:%v", hostname, port)), WithTokenPath(tp), WithToken(token))
signer, err = provider.Signer(ctx)

Check failure on line 220 in signer/fulcio/fulcio_test.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to signer (ineffassign)
require.ErrorContains(t, err, "only one of --fulcio-token-path or --fulcio-raw-token can be used")
}

func generateCertChain(t *testing.T) []string {
Expand Down

0 comments on commit d9e960f

Please sign in to comment.