Skip to content

Commit f7dcc07

Browse files
committed
refactor(api): replace APIKeyGet methods with unified APIKeyResolve
- Replace APIKeyGet and APIKeyGetByName with APIKeyResolve method - Add APIKeyResolver enum with IDResolver and NameResolver options - Update all service calls to use new resolver pattern - Consolidate API key lookup logic into single method with resolver strategy - Fix syntax error in CreateAPIKey method BREAKING CHANGE: removes APIKeyGet and APIKeyGetByName methods from APIKeyStore interface
1 parent a624421 commit f7dcc07

File tree

8 files changed

+182
-193
lines changed

8 files changed

+182
-193
lines changed

api/services/api-key.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func (s *service) CreateAPIKey(ctx context.Context, req *requests.CreateAPIKey)
4141
case 30, 60, 90:
4242
expiresIn = clock.Now().AddDate(0, 0, req.ExpiresAt).Unix()
4343
case 365:
44-
expiresIn = clock.Now().AddDate(1, 0, 0).Unix()
44+
expiresIn = clock.Now().AddDate(1, 0, 0).Unix(Get)
4545
case -1:
4646
expiresIn = -1
4747
default:
@@ -87,7 +87,7 @@ func (s *service) CreateAPIKey(ctx context.Context, req *requests.CreateAPIKey)
8787

8888
// As we need to return the plain key in the create service, we temporarily set
8989
// the apiKey.ID to the plain key here.
90-
apiKey, _ := s.store.APIKeyGet(ctx, hashedKey)
90+
apiKey, _ := s.store.APIKeyResolve(ctx, store.APIKeyIDResolver, hashedKey)
9191
apiKey.ID = req.Key
9292

9393
return responses.CreateAPIKeyFromModel(apiKey), nil

api/services/api-key_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ func TestCreateAPIKey(t *testing.T) {
275275
Return(hashedKey, nil).
276276
Once()
277277
storeMock.
278-
On("APIKeyGet", ctx, hashedKey).
278+
On("APIKeyResolve", ctx, store.APIKeyIDResolver, hashedKey).
279279
Return(&models.APIKey{
280280
ID: hashedKey,
281281
Name: "dev",
@@ -353,7 +353,7 @@ func TestCreateAPIKey(t *testing.T) {
353353
Return(hashedKey, nil).
354354
Once()
355355
storeMock.
356-
On("APIKeyGet", ctx, hashedKey).
356+
On("APIKeyResolve", ctx, store.APIKeyIDResolver, hashedKey).
357357
Return(&models.APIKey{
358358
ID: hashedKey,
359359
Name: "dev",

api/services/auth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ func (s *service) AuthAPIKey(ctx context.Context, key string) (*models.APIKey, e
431431
hashedKey := hex.EncodeToString(keySum[:])
432432

433433
var err error
434-
if apiKey, err = s.store.APIKeyGet(ctx, hashedKey); err != nil {
434+
if apiKey, err = s.store.APIKeyResolve(ctx, store.APIKeyIDResolver, hashedKey); err != nil {
435435
return nil, NewErrAPIKeyNotFound("", err)
436436
}
437437
}

api/services/auth_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,7 +2424,7 @@ func TestAuthAPIKey(t *testing.T) {
24242424
keySum := sha256.Sum256([]byte("00000000-0000-4000-0000-000000000000"))
24252425
hashedKey := hex.EncodeToString(keySum[:])
24262426
storeMock.
2427-
On("APIKeyGet", ctx, hashedKey).
2427+
On("APIKeyResolve", ctx, store.APIKeyIDResolver, hashedKey).
24282428
Return(nil, errors.New("error", "", 0)).
24292429
Once()
24302430
},
@@ -2444,7 +2444,7 @@ func TestAuthAPIKey(t *testing.T) {
24442444
keySum := sha256.Sum256([]byte("00000000-0000-4000-0000-000000000000"))
24452445
hashedKey := hex.EncodeToString(keySum[:])
24462446
storeMock.
2447-
On("APIKeyGet", ctx, hashedKey).
2447+
On("APIKeyResolve", ctx, store.APIKeyIDResolver, hashedKey).
24482448
Return(
24492449
&models.APIKey{
24502450
Name: "dev",
@@ -2470,7 +2470,7 @@ func TestAuthAPIKey(t *testing.T) {
24702470
keySum := sha256.Sum256([]byte("00000000-0000-4000-0000-000000000000"))
24712471
hashedKey := hex.EncodeToString(keySum[:])
24722472
storeMock.
2473-
On("APIKeyGet", ctx, hashedKey).
2473+
On("APIKeyResolve", ctx, store.APIKeyIDResolver, hashedKey).
24742474
Return(
24752475
&models.APIKey{
24762476
Name: "dev",

api/store/api_key.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@ import (
77
"github.com/shellhub-io/shellhub/pkg/models"
88
)
99

10+
type APIKeyResolver uint
11+
12+
const (
13+
APIKeyIDResolver APIKeyResolver = iota + 1
14+
APIKeyNameResolver
15+
)
16+
1017
type APIKeyStore interface {
1118
// APIKeyCreate creates an API key with the provided data. Returns the inserted ID and an error if any.
1219
APIKeyCreate(ctx context.Context, APIKey *models.APIKey) (insertedID string, err error)
1320

14-
// APIKeyGet retrieves an API key based on its ID. Returns the API key and an error if any.
15-
APIKeyGet(ctx context.Context, id string) (apiKey *models.APIKey, err error)
16-
17-
// APIKeyGetByName retrieves an API key based on its name and tenant ID. Returns the API key and an error if any.
18-
APIKeyGetByName(ctx context.Context, tenantID string, name string) (apiKey *models.APIKey, err error)
21+
// APIKeyResolve fetches an API key using a specific resolver within a given tenant ID.
22+
//
23+
// It returns the resolved API key if found and an error, if any.
24+
APIKeyResolve(ctx context.Context, resolver APIKeyResolver, value string, opts ...QueryOption) (*models.APIKey, error)
1925

2026
// APIKeyConflicts reports whether the target contains conflicting attributes with the database. Pass zero values for
2127
// attributes you do not wish to match on. It returns an array of conflicting attribute fields and an error, if any.

api/store/mocks/store.go

Lines changed: 37 additions & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/store/mongo/api-key.go

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,6 @@ func (s *Store) APIKeyCreate(ctx context.Context, apiKey *models.APIKey) (string
2424
return res.InsertedID.(string), nil
2525
}
2626

27-
func (s *Store) APIKeyGet(ctx context.Context, id string) (*models.APIKey, error) {
28-
apiKey := new(models.APIKey)
29-
if err := s.db.Collection("api_keys").FindOne(ctx, bson.M{"_id": id}).Decode(apiKey); err != nil {
30-
return nil, FromMongoError(err)
31-
}
32-
33-
return apiKey, nil
34-
}
35-
36-
func (s *Store) APIKeyGetByName(ctx context.Context, tenantID string, name string) (*models.APIKey, error) {
37-
apiKey := new(models.APIKey)
38-
if err := s.db.Collection("api_keys").FindOne(ctx, bson.M{"tenant_id": tenantID, "name": name}).Decode(&apiKey); err != nil {
39-
return nil, FromMongoError(err)
40-
}
41-
42-
return apiKey, nil
43-
}
44-
4527
func (s *Store) APIKeyConflicts(ctx context.Context, tenantID string, target *models.APIKeyConflicts) ([]string, bool, error) {
4628
pipeline := []bson.M{
4729
{
@@ -80,6 +62,37 @@ func (s *Store) APIKeyConflicts(ctx context.Context, tenantID string, target *mo
8062
return conflicts, len(conflicts) > 0, nil
8163
}
8264

65+
func (s *Store) APIKeyResolve(ctx context.Context, resolver store.APIKeyResolver, value string, opts ...store.QueryOption) (*models.APIKey, error) {
66+
matchStage := bson.M{}
67+
switch resolver {
68+
case store.APIKeyIDResolver:
69+
matchStage["_id"] = value
70+
case store.APIKeyNameResolver:
71+
matchStage["name"] = value
72+
}
73+
74+
for _, opt := range opts {
75+
if err := opt(context.WithValue(ctx, "query", &matchStage)); err != nil {
76+
return nil, err
77+
}
78+
}
79+
80+
cursor, err := s.db.Collection("api_keys").Aggregate(ctx, []bson.M{{"$match": matchStage}})
81+
if err != nil {
82+
return nil, FromMongoError(err)
83+
}
84+
defer cursor.Close(ctx)
85+
86+
cursor.Next(ctx)
87+
88+
apiKey := new(models.APIKey)
89+
if err := cursor.Decode(&apiKey); err != nil {
90+
return nil, FromMongoError(err)
91+
}
92+
93+
return apiKey, nil
94+
}
95+
8396
func (s *Store) APIKeyList(ctx context.Context, tenantID string, paginator query.Paginator, sorter query.Sorter) ([]models.APIKey, int, error) {
8497
query := []bson.M{
8598
{

0 commit comments

Comments
 (0)