diff --git a/cli/root.go b/cli/root.go index 18a6f423f0..e7104e6428 100644 --- a/cli/root.go +++ b/cli/root.go @@ -55,11 +55,12 @@ const ( envNoVersionCheck = "CODER_NO_VERSION_WARNING" envNoFeatureWarning = "CODER_NO_FEATURE_WARNING" envExperimental = "CODER_EXPERIMENTAL" + envSessionToken = "CODER_SESSION_TOKEN" + envURL = "CODER_URL" ) var ( errUnauthenticated = xerrors.New(notLoggedInMessage) - envSessionToken = "CODER_SESSION_TOKEN" ) func init() { @@ -173,7 +174,7 @@ func Root(subcommands []*cobra.Command) *cobra.Command { cmd.SetUsageTemplate(usageTemplate()) - cmd.PersistentFlags().String(varURL, "", "URL to a deployment.") + cliflag.String(cmd.PersistentFlags(), varURL, "", envURL, "", "URL to a deployment.") cliflag.Bool(cmd.PersistentFlags(), varNoVersionCheck, "", envNoVersionCheck, false, "Suppress warning when client and server versions do not match.") cliflag.Bool(cmd.PersistentFlags(), varNoFeatureWarning, "", envNoFeatureWarning, false, "Suppress warnings about unlicensed features.") cliflag.String(cmd.PersistentFlags(), varToken, "", envSessionToken, "", fmt.Sprintf("Specify an authentication token. For security reasons setting %s is preferred.", envSessionToken)) diff --git a/coderd/httpmw/apikey.go b/coderd/httpmw/apikey.go index da80337f76..5e409a58d7 100644 --- a/coderd/httpmw/apikey.go +++ b/coderd/httpmw/apikey.go @@ -204,7 +204,7 @@ func ExtractAPIKey(cfg ExtractAPIKeyConfig) func(http.Handler) http.Handler { // Tracks if the API key has properties updated changed = false ) - if key.LoginType != database.LoginTypePassword { + if key.LoginType == database.LoginTypeGithub || key.LoginType == database.LoginTypeOIDC { link, err = cfg.DB.GetUserLinkByUserIDLoginType(r.Context(), database.GetUserLinkByUserIDLoginTypeParams{ UserID: key.UserID, LoginType: key.LoginType, diff --git a/coderd/httpmw/apikey_test.go b/coderd/httpmw/apikey_test.go index 2ad9b8b5be..7bfdf360b3 100644 --- a/coderd/httpmw/apikey_test.go +++ b/coderd/httpmw/apikey_test.go @@ -589,6 +589,45 @@ func TestAPIKey(t *testing.T) { require.Equal(t, http.StatusOK, res.StatusCode) require.EqualValues(t, 1, atomic.LoadInt64(&count)) }) + + t.Run("Tokens", func(t *testing.T) { + t.Parallel() + var ( + db = databasefake.New() + id, secret = randomAPIKeyParts() + hashed = sha256.Sum256([]byte(secret)) + r = httptest.NewRequest("GET", "/", nil) + rw = httptest.NewRecorder() + user = createUser(r.Context(), t, db) + ) + r.Header.Set(codersdk.SessionCustomHeader, fmt.Sprintf("%s-%s", id, secret)) + + sentAPIKey, err := db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{ + ID: id, + HashedSecret: hashed[:], + LoginType: database.LoginTypeToken, + LastUsed: database.Now(), + ExpiresAt: database.Now().AddDate(0, 0, 1), + UserID: user.ID, + Scope: database.APIKeyScopeAll, + }) + require.NoError(t, err) + + httpmw.ExtractAPIKey(httpmw.ExtractAPIKeyConfig{ + DB: db, + RedirectToLogin: false, + })(successHandler).ServeHTTP(rw, r) + res := rw.Result() + defer res.Body.Close() + require.Equal(t, http.StatusOK, res.StatusCode) + + gotAPIKey, err := db.GetAPIKeyByID(r.Context(), id) + require.NoError(t, err) + + require.Equal(t, sentAPIKey.LastUsed, gotAPIKey.LastUsed) + require.Equal(t, sentAPIKey.ExpiresAt, gotAPIKey.ExpiresAt) + require.Equal(t, sentAPIKey.LoginType, gotAPIKey.LoginType) + }) } func createUser(ctx context.Context, t *testing.T, db database.Store) database.User {