Skip to content

Commit 216a951

Browse files
author
Mike Zorn
authored
fix: Handle api_key prefix in auth header (#495)
* fix lint error * support api_key prefix when authenticating
1 parent b2a5f1e commit 216a951

File tree

4 files changed

+74
-5
lines changed

4 files changed

+74
-5
lines changed

internal/dev_server/db/backup/sqllite_backup.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import (
44
"context"
55
"database/sql"
66
"fmt"
7-
sqllite "github.com/mattn/go-sqlite3"
8-
"github.com/pkg/errors"
97
"io"
108
"log"
119
"os"
1210
"sync"
1311
"sync/atomic"
12+
13+
sqllite "github.com/mattn/go-sqlite3"
14+
"github.com/pkg/errors"
1415
)
1516

1617
var c atomic.Int32
@@ -195,7 +196,7 @@ func runBackup(backupDbConn *sqllite.SQLiteConn, srcDbConn *sqllite.SQLiteConn,
195196
}(backup)
196197

197198
var isDone = false
198-
var stepError error = nil
199+
var stepError error
199200
for !isDone {
200201
isDone, stepError = backup.Step(1)
201202
if stepError != nil {

internal/dev_server/db/sqlite.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import (
44
"context"
55
"database/sql"
66
"encoding/json"
7-
_ "github.com/mattn/go-sqlite3"
8-
"github.com/pkg/errors"
97
"io"
108
"os"
119

10+
_ "github.com/mattn/go-sqlite3"
11+
"github.com/pkg/errors"
12+
1213
"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
1314
"github.com/launchdarkly/ldcli/internal/dev_server/db/backup"
1415
"github.com/launchdarkly/ldcli/internal/dev_server/model"
@@ -380,6 +381,9 @@ func (s *Sqlite) RestoreBackup(ctx context.Context, stream io.Reader) (string, e
380381

381382
func (s *Sqlite) CreateBackup(ctx context.Context) (io.ReadCloser, int64, error) {
382383
backupPath, err := s.backupManager.MakeBackupFile(ctx)
384+
if err != nil {
385+
return nil, 0, errors.Wrapf(err, "unable to make backup file, %s", backupPath)
386+
}
383387
fi, err := os.Open(backupPath)
384388
if err != nil {
385389
return nil, 0, errors.Wrapf(err, "unable to open backup db at %s", backupPath)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package sdk
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
"time"
9+
10+
"github.com/gorilla/mux"
11+
"github.com/launchdarkly/go-sdk-common/v3/ldcontext"
12+
"github.com/launchdarkly/ldcli/internal/dev_server/model"
13+
"github.com/launchdarkly/ldcli/internal/dev_server/model/mocks"
14+
"github.com/stretchr/testify/assert"
15+
"go.uber.org/mock/gomock"
16+
)
17+
18+
var exampleProjectKey = "my-project"
19+
var exampleProject = &model.Project{
20+
Key: exampleProjectKey,
21+
SourceEnvironmentKey: "my-environment",
22+
Context: ldcontext.Context{},
23+
LastSyncTime: time.Unix(0, 0),
24+
AllFlagsState: make(model.FlagsState),
25+
AvailableVariations: nil,
26+
}
27+
28+
func TestMobileAuth(t *testing.T) {
29+
mockController := gomock.NewController(t)
30+
store := mocks.NewMockStore(mockController)
31+
observers := model.NewObservers()
32+
33+
// Wire up sdk routes in test server
34+
router := mux.NewRouter()
35+
router.Use(model.ObserversMiddleware(observers))
36+
router.Use(model.StoreMiddleware(store))
37+
BindRoutes(router)
38+
39+
t.Run("given project key prefixed with api_key, it should authenticate successfully", func(t *testing.T) {
40+
store.EXPECT().GetDevProject(gomock.Any(), exampleProjectKey).Return(exampleProject, nil)
41+
store.EXPECT().GetOverridesForProject(gomock.Any(), exampleProjectKey).Return(nil, nil)
42+
43+
req := httptest.NewRequest("GET", "/msdk/evalx/eyJrZXkiOiJib2FyZCBjYXQifQ==", nil)
44+
req.Header.Set("Authorization", fmt.Sprintf("api_key %s", exampleProjectKey))
45+
rec := httptest.NewRecorder()
46+
router.ServeHTTP(rec, req)
47+
48+
assert.Equal(t, http.StatusOK, rec.Code)
49+
})
50+
51+
t.Run("given just the project key, it should authenticate successfully", func(t *testing.T) {
52+
store.EXPECT().GetDevProject(gomock.Any(), exampleProjectKey).Return(exampleProject, nil)
53+
store.EXPECT().GetOverridesForProject(gomock.Any(), exampleProjectKey).Return(nil, nil)
54+
55+
req := httptest.NewRequest("GET", "/msdk/evalx/eyJrZXkiOiJib2FyZCBjYXQifQ==", nil)
56+
req.Header.Set("Authorization", exampleProjectKey)
57+
rec := httptest.NewRecorder()
58+
router.ServeHTTP(rec, req)
59+
60+
assert.Equal(t, http.StatusOK, rec.Code)
61+
})
62+
}

internal/dev_server/sdk/project_key_middleware.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sdk
33
import (
44
"context"
55
"net/http"
6+
"strings"
67

78
"github.com/gorilla/mux"
89
)
@@ -38,6 +39,7 @@ func GetProjectKeyFromAuthorizationHeader(handler http.Handler) http.Handler {
3839
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
3940
ctx := request.Context()
4041
projectKey := request.Header.Get("Authorization")
42+
projectKey = strings.TrimPrefix(projectKey, "api_key ") // some sdks set this as a prefix
4143
if projectKey == "" {
4244
http.Error(writer, "project key not on Authorization header", http.StatusUnauthorized)
4345
return

0 commit comments

Comments
 (0)