github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/service/api_key.go (about) 1 package service 2 3 import ( 4 "context" 5 "errors" 6 7 "gorm.io/gorm" 8 9 "github.com/pyroscope-io/pyroscope/pkg/model" 10 ) 11 12 type APIKeyService struct { 13 db *gorm.DB 14 bcryptCost int 15 } 16 17 func NewAPIKeyService(db *gorm.DB, bcryptCost int) APIKeyService { 18 return APIKeyService{ 19 db: db, 20 bcryptCost: bcryptCost, 21 } 22 } 23 24 func (svc APIKeyService) CreateAPIKey(ctx context.Context, params model.CreateAPIKeyParams) (model.APIKey, string, error) { 25 if err := params.Validate(); err != nil { 26 return model.APIKey{}, "", err 27 } 28 apiKey := model.APIKey{ 29 Name: params.Name, 30 Hash: []byte{}, 31 Role: params.Role, 32 ExpiresAt: params.ExpiresAt, 33 } 34 var secret string 35 err := svc.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { 36 _, err := findAPIKeyByName(tx, params.Name) 37 switch { 38 case errors.Is(err, model.ErrAPIKeyNotFound): 39 case err == nil: 40 return model.ErrAPIKeyNameExists 41 default: 42 return err 43 } 44 if err = tx.Create(&apiKey).Error; err != nil { 45 return err 46 } 47 var hash []byte 48 if secret, hash, err = model.GenerateAPIKeyWithCost(apiKey.ID, svc.bcryptCost); err != nil { 49 return err 50 } 51 apiKey.Hash = hash 52 return tx.Updates(&model.APIKey{ID: apiKey.ID, Hash: hash}).Error 53 }) 54 if err != nil { 55 return model.APIKey{}, "", err 56 } 57 return apiKey, secret, nil 58 } 59 60 func (svc APIKeyService) FindAPIKeyByID(ctx context.Context, id uint) (model.APIKey, error) { 61 return findAPIKeyByID(svc.db.WithContext(ctx), id) 62 } 63 64 func (svc APIKeyService) FindAPIKeyByName(ctx context.Context, name string) (model.APIKey, error) { 65 return findAPIKeyByName(svc.db.WithContext(ctx), name) 66 } 67 68 func findAPIKeyByID(tx *gorm.DB, id uint) (model.APIKey, error) { 69 return findAPIKey(tx, model.APIKey{ID: id}) 70 } 71 72 func findAPIKeyByName(tx *gorm.DB, apiKeyName string) (model.APIKey, error) { 73 return findAPIKey(tx, model.APIKey{Name: apiKeyName}) 74 } 75 76 func findAPIKey(tx *gorm.DB, k model.APIKey) (model.APIKey, error) { 77 var apiKey model.APIKey 78 r := tx.Where(k).First(&apiKey) 79 switch { 80 case r.Error == nil: 81 return apiKey, nil 82 case errors.Is(r.Error, gorm.ErrRecordNotFound): 83 return model.APIKey{}, model.ErrAPIKeyNotFound 84 default: 85 return model.APIKey{}, r.Error 86 } 87 } 88 89 func (svc APIKeyService) GetAllAPIKeys(ctx context.Context) ([]model.APIKey, error) { 90 var apiKeys []model.APIKey 91 return apiKeys, svc.db.WithContext(ctx).Find(&apiKeys).Error 92 } 93 94 func (svc APIKeyService) DeleteAPIKeyByID(ctx context.Context, id uint) error { 95 return svc.db.WithContext(ctx).Delete(&model.APIKey{}, id).Error 96 }