-
Notifications
You must be signed in to change notification settings - Fork 10
fix: Handle api_key prefix in auth header #495
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package sdk | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "net/http" | ||
| "net/http/httptest" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/gorilla/mux" | ||
| "github.com/launchdarkly/go-sdk-common/v3/ldcontext" | ||
| "github.com/launchdarkly/ldcli/internal/dev_server/model" | ||
| "github.com/launchdarkly/ldcli/internal/dev_server/model/mocks" | ||
| "github.com/stretchr/testify/assert" | ||
| "go.uber.org/mock/gomock" | ||
| ) | ||
|
|
||
| var exampleProjectKey = "my-project" | ||
| var exampleProject = &model.Project{ | ||
| Key: exampleProjectKey, | ||
| SourceEnvironmentKey: "my-environment", | ||
| Context: ldcontext.Context{}, | ||
| LastSyncTime: time.Unix(0, 0), | ||
| AllFlagsState: make(model.FlagsState), | ||
| AvailableVariations: nil, | ||
| } | ||
|
|
||
| func TestMobileAuth(t *testing.T) { | ||
| mockController := gomock.NewController(t) | ||
| store := mocks.NewMockStore(mockController) | ||
| observers := model.NewObservers() | ||
|
|
||
| // Wire up sdk routes in test server | ||
| router := mux.NewRouter() | ||
| router.Use(model.ObserversMiddleware(observers)) | ||
| router.Use(model.StoreMiddleware(store)) | ||
| BindRoutes(router) | ||
|
|
||
| t.Run("given project key prefixed with api_key, it should authenticate successfully", func(t *testing.T) { | ||
| store.EXPECT().GetDevProject(gomock.Any(), exampleProjectKey).Return(exampleProject, nil) | ||
| store.EXPECT().GetOverridesForProject(gomock.Any(), exampleProjectKey).Return(nil, nil) | ||
|
|
||
| req := httptest.NewRequest("GET", "/msdk/evalx/eyJrZXkiOiJib2FyZCBjYXQifQ==", nil) | ||
| req.Header.Set("Authorization", fmt.Sprintf("api_key %s", exampleProjectKey)) | ||
| rec := httptest.NewRecorder() | ||
| router.ServeHTTP(rec, req) | ||
|
|
||
| assert.Equal(t, http.StatusOK, rec.Code) | ||
| }) | ||
|
|
||
| t.Run("given just the project key, it should authenticate successfully", func(t *testing.T) { | ||
| store.EXPECT().GetDevProject(gomock.Any(), exampleProjectKey).Return(exampleProject, nil) | ||
| store.EXPECT().GetOverridesForProject(gomock.Any(), exampleProjectKey).Return(nil, nil) | ||
|
|
||
| req := httptest.NewRequest("GET", "/msdk/evalx/eyJrZXkiOiJib2FyZCBjYXQifQ==", nil) | ||
| req.Header.Set("Authorization", exampleProjectKey) | ||
| rec := httptest.NewRecorder() | ||
| router.ServeHTTP(rec, req) | ||
|
|
||
| assert.Equal(t, http.StatusOK, rec.Code) | ||
| }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package sdk | |
| import ( | ||
| "context" | ||
| "net/http" | ||
| "strings" | ||
|
|
||
| "github.com/gorilla/mux" | ||
| ) | ||
|
|
@@ -38,6 +39,7 @@ func GetProjectKeyFromAuthorizationHeader(handler http.Handler) http.Handler { | |
| return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { | ||
| ctx := request.Context() | ||
| projectKey := request.Header.Get("Authorization") | ||
| projectKey = strings.TrimPrefix(projectKey, "api_key ") // some sdks set this as a prefix | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @keelerm84 Are there other scenarios we should be aware of for auth key formats?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure. The Maybe that's something more aligned with the integrations team, or whoever is in charge of the auto-generated API SDKs?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol glad we were both surprised by this behavior. It looks like iOS is doing this prefixing thing. Looks like same for android.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤯 Well that IS surprising. I wonder if that is still necessary. I checked the relay, and there is a
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ooh. Thank you for looking at the relay implementation. If that's all it supports, I think we're all good here. |
||
| if projectKey == "" { | ||
| http.Error(writer, "project key not on Authorization header", http.StatusUnauthorized) | ||
| return | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof nice catch - should we make a follow up item to add a linter rule to catch ineffectual assigns to
err?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linter is running if you use pre-commit, but it doesn't look like pre-commit checks are being run in ci.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But yeah. A follow up item to fixup the CI linter is a good idea.