satellite: Rename "acct mgmt api" to "rest api"

"REST API" is a more accurate descriptor of the generated API in the
console package than "account management API". The generated API is very
flexible and will allow us to implement many more endpoints outside the
scope of "account management", and "account management" is not very well
defined to begin with.

Change-Id: Ie87faeaa3c743ef4371eaf0edd2826303d592da7
This commit is contained in:
Moby von Briesen 2022-04-12 12:59:07 -04:00 committed by Maximillian von Briesen
parent 1ed36e9fea
commit ed5ebb2527
20 changed files with 130 additions and 129 deletions

View File

@ -21,7 +21,7 @@ import (
"storj.io/storj/private/version/checker"
"storj.io/storj/satellite/admin"
"storj.io/storj/satellite/buckets"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/metabase"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/stripecoinpayments"
@ -65,8 +65,8 @@ type Admin struct {
Service *buckets.Service
}
AccountManagementAPIKeys struct {
Service *accountmanagementapikeys.Service
REST struct {
Keys *restkeys.Service
}
}
@ -87,8 +87,8 @@ func NewAdmin(log *zap.Logger, full *identity.FullIdentity, db DB, metabaseDB *m
peer.Buckets.Service = buckets.NewService(db.Buckets(), metabaseDB)
}
{ // setup account management api keys
peer.AccountManagementAPIKeys.Service = accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), config.AccountManagementAPIKeys)
{ // setup rest keys
peer.REST.Keys = restkeys.NewService(db.OIDC().OAuthTokens(), config.RESTKeys)
}
{ // setup debug
@ -173,7 +173,7 @@ func NewAdmin(log *zap.Logger, full *identity.FullIdentity, db DB, metabaseDB *m
adminConfig := config.Admin
adminConfig.AuthorizationToken = config.Console.AuthToken
peer.Admin.Server = admin.NewServer(log.Named("admin"), peer.Admin.Listener, peer.DB, peer.Buckets.Service, peer.AccountManagementAPIKeys.Service, peer.Payments.Accounts, adminConfig)
peer.Admin.Server = admin.NewServer(log.Named("admin"), peer.Admin.Listener, peer.DB, peer.Buckets.Service, peer.REST.Keys, peer.Payments.Accounts, adminConfig)
peer.Servers.Add(lifecycle.Item{
Name: "admin",
Run: peer.Admin.Server.Run,

View File

@ -15,7 +15,7 @@ import (
"github.com/gorilla/mux"
)
func (server *Server) addAccountManagementAPIKey(w http.ResponseWriter, r *http.Request) {
func (server *Server) addRESTKey(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
@ -66,7 +66,7 @@ func (server *Server) addAccountManagementAPIKey(w http.ResponseWriter, r *http.
}
}
apiKey, expiresAt, err := server.accountManagementAPIKeys.Create(ctx, user.ID, expiration)
apiKey, expiresAt, err := server.restKeys.Create(ctx, user.ID, expiration)
if err != nil {
sendJSONError(w, "api key creation failed",
err.Error(), http.StatusInternalServerError)
@ -91,7 +91,7 @@ func (server *Server) addAccountManagementAPIKey(w http.ResponseWriter, r *http.
sendJSONData(w, http.StatusOK, data)
}
func (server *Server) revokeAccountManagementAPIKey(w http.ResponseWriter, r *http.Request) {
func (server *Server) revokeRESTKey(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
@ -102,7 +102,7 @@ func (server *Server) revokeAccountManagementAPIKey(w http.ResponseWriter, r *ht
return
}
err := server.accountManagementAPIKeys.Revoke(ctx, apiKey)
err := server.restKeys.Revoke(ctx, apiKey)
if err != nil {
sendJSONError(w, "failed to revoke api key",
err.Error(), http.StatusNotFound)

View File

@ -22,7 +22,7 @@ import (
"storj.io/storj/satellite/oidc"
)
func TestAccountManagementAPIKeys(t *testing.T) {
func TestRESTKeys(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1,
StorageNodeCount: 0,
@ -35,14 +35,14 @@ func TestAccountManagementAPIKeys(t *testing.T) {
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
address := planet.Satellites[0].Admin.Admin.Listener.Addr()
satellite := planet.Satellites[0]
keyService := satellite.API.AccountManagementAPIKeys.Service
keyService := satellite.API.REST.Keys
user, err := planet.Satellites[0].DB.Console().Users().GetByEmail(ctx, planet.Uplinks[0].Projects[0].Owner.Email)
require.NoError(t, err)
t.Run("create with default expiration", func(t *testing.T) {
body := strings.NewReader(`{"expiration":""}`)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("http://"+address.String()+"/api/accountmanagementapikeys/%s", user.Email), body)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("http://"+address.String()+"/api/restkeys/%s", user.Email), body)
require.NoError(t, err)
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
@ -73,7 +73,7 @@ func TestAccountManagementAPIKeys(t *testing.T) {
require.False(t, exp.Before(now))
// check the expiration is around the time we expect
defaultExpiration := satellite.Config.AccountManagementAPIKeys.DefaultExpiration
defaultExpiration := satellite.Config.RESTKeys.DefaultExpiration
require.True(t, output.ExpiresAt.After(now.Add(defaultExpiration)))
require.True(t, output.ExpiresAt.Before(now.Add(defaultExpiration+time.Hour)))
})
@ -81,7 +81,7 @@ func TestAccountManagementAPIKeys(t *testing.T) {
t.Run("create with custom expiration", func(t *testing.T) {
durationString := "3h"
body := strings.NewReader(fmt.Sprintf(`{"expiration":"%s"}`, durationString))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("http://"+address.String()+"/api/accountmanagementapikeys/%s", user.Email), body)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("http://"+address.String()+"/api/restkeys/%s", user.Email), body)
require.NoError(t, err)
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
@ -125,13 +125,13 @@ func TestAccountManagementAPIKeys(t *testing.T) {
expiresAt, err := keyService.InsertIntoDB(ctx, oidc.OAuthToken{
UserID: user.ID,
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: hash,
}, time.Now(), time.Hour)
require.NoError(t, err)
require.False(t, expiresAt.IsZero())
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("http://"+address.String()+"/api/accountmanagementapikeys/%s/revoke", apiKey), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("http://"+address.String()+"/api/restkeys/%s/revoke", apiKey), nil)
require.NoError(t, err)
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)

View File

@ -21,7 +21,7 @@ import (
adminui "storj.io/storj/satellite/admin/ui"
"storj.io/storj/satellite/buckets"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/oidc"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/stripecoinpayments"
@ -56,10 +56,10 @@ type Server struct {
listener net.Listener
server http.Server
db DB
payments payments.Accounts
buckets *buckets.Service
accountManagementAPIKeys *accountmanagementapikeys.Service
db DB
payments payments.Accounts
buckets *buckets.Service
restKeys *restkeys.Service
nowFn func() time.Time
@ -67,16 +67,16 @@ type Server struct {
}
// NewServer returns a new administration Server.
func NewServer(log *zap.Logger, listener net.Listener, db DB, buckets *buckets.Service, accountManagementAPIKeys *accountmanagementapikeys.Service, accounts payments.Accounts, config Config) *Server {
func NewServer(log *zap.Logger, listener net.Listener, db DB, buckets *buckets.Service, restKeys *restkeys.Service, accounts payments.Accounts, config Config) *Server {
server := &Server{
log: log,
listener: listener,
db: db,
payments: accounts,
buckets: buckets,
accountManagementAPIKeys: accountManagementAPIKeys,
db: db,
payments: accounts,
buckets: buckets,
restKeys: restKeys,
nowFn: time.Now,
@ -110,8 +110,8 @@ func NewServer(log *zap.Logger, listener net.Listener, db DB, buckets *buckets.S
api.HandleFunc("/projects/{project}/buckets/{bucket}/geofence", server.createGeofenceForBucket).Methods("POST")
api.HandleFunc("/projects/{project}/buckets/{bucket}/geofence", server.deleteGeofenceForBucket).Methods("DELETE")
api.HandleFunc("/apikeys/{apikey}", server.deleteAPIKey).Methods("DELETE")
api.HandleFunc("/accountmanagementapikeys/{useremail}", server.addAccountManagementAPIKey).Methods("POST")
api.HandleFunc("/accountmanagementapikeys/{apikey}/revoke", server.revokeAccountManagementAPIKey).Methods("PUT")
api.HandleFunc("/restkeys/{useremail}", server.addRESTKey).Methods("POST")
api.HandleFunc("/restkeys/{apikey}/revoke", server.revokeRESTKey).Methods("PUT")
// This handler must be the last one because it uses the root as prefix,
// otherwise will try to serve all the handlers set after this one.

View File

@ -372,28 +372,28 @@ Blank fields will not be updated.`,
}
}
],
account_management_api_keys: [
rest_api_keys: [
{
name: 'create',
desc: 'Create an account management API key',
desc: 'Create a REST key',
//params: [['API key', new InputText('text', true)]],
params: [
["user's email", new InputText('text', true)],
['expiration', new InputText('text', false)]
],
func: async (useremail: string, expiration?: string): Promise<Record<string, unknown>> => {
return this.fetch('POST', `accountmanagementapikeys/${useremail}`, null, {
return this.fetch('POST', `restkeys/${useremail}`, null, {
expiration
});
}
},
{
name: 'revoke',
desc: 'Revoke an account management API key',
desc: 'Revoke a REST key',
//params: [['API key', new InputText('text', true)]],
params: [['api key', new InputText('text', true)]],
func: async (apikey: string): Promise<Record<string, unknown>> => {
return this.fetch('PUT', `accountmanagementapikeys/${apikey}/revoke`);
return this.fetch('PUT', `restkeys/${apikey}/revoke`);
}
}
]

View File

@ -34,9 +34,9 @@ import (
"storj.io/storj/satellite/analytics"
"storj.io/storj/satellite/buckets"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/consoleweb"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/contact"
"storj.io/storj/satellite/gracefulexit"
"storj.io/storj/satellite/inspector"
@ -137,8 +137,8 @@ type API struct {
Stripe stripecoinpayments.StripeClient
}
AccountManagementAPIKeys struct {
Service *accountmanagementapikeys.Service
REST struct {
Keys *restkeys.Service
}
Console struct {
@ -578,7 +578,7 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
}
{ // setup account management api keys
peer.AccountManagementAPIKeys.Service = accountmanagementapikeys.NewService(peer.DB.OIDC().OAuthTokens(), config.AccountManagementAPIKeys)
peer.REST.Keys = restkeys.NewService(peer.DB.OIDC().OAuthTokens(), config.RESTKeys)
}
{ // setup console
@ -595,7 +595,7 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
peer.Log.Named("console:service"),
&consoleauth.Hmac{Secret: []byte(consoleConfig.AuthTokenSecret)},
peer.DB.Console(),
peer.AccountManagementAPIKeys.Service,
peer.REST.Keys,
peer.DB.ProjectAccounting(),
peer.Accounting.ProjectUsage,
peer.Buckets.Service,

View File

@ -30,8 +30,8 @@ type APIKeys interface {
Delete(ctx context.Context, id uuid.UUID) error
}
// AccountManagementAPIKeys is an interface for account management api key operations.
type AccountManagementAPIKeys interface {
// RESTKeys is an interface for rest key operations.
type RESTKeys interface {
Create(ctx context.Context, userID uuid.UUID, expiration time.Duration) (apiKey string, expiresAt time.Time, err error)
GetUserAndExpirationFromKey(ctx context.Context, apiKey string) (userID uuid.UUID, exp time.Time, err error)
Revoke(ctx context.Context, apiKey string) (err error)

View File

@ -15,6 +15,7 @@ import (
)
func main() {
// definition for REST API
a := &apigen.API{
Version: "v0",
Description: "",

View File

@ -24,9 +24,9 @@ import (
"storj.io/storj/satellite/accounting/live"
"storj.io/storj/satellite/analytics"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/consoleweb/consoleql"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/paymentsconfig"
@ -99,7 +99,7 @@ func TestGraphqlMutation(t *testing.T) {
log.Named("console"),
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
db.Console(),
accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.AccountManagementAPIKeys),
restkeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.RESTKeys),
db.ProjectAccounting(),
projectUsage,
sat.API.Buckets.Service,

View File

@ -21,9 +21,9 @@ import (
"storj.io/storj/satellite/accounting/live"
"storj.io/storj/satellite/analytics"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/consoleweb/consoleql"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/paymentsconfig"
@ -83,7 +83,7 @@ func TestGraphqlQuery(t *testing.T) {
log.Named("console"),
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
db.Console(),
accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.AccountManagementAPIKeys),
restkeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.RESTKeys),
db.ProjectAccounting(),
projectUsage,
sat.API.Buckets.Service,

View File

@ -1,7 +1,7 @@
// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
package accountmanagementapikeys
package restkeys
import (
"context"
@ -20,8 +20,8 @@ import (
var mon = monkit.Package()
var (
// Error describes internal account management api keys error.
Error = errs.Class("account management api keys service")
// Error describes internal rest keys error.
Error = errs.Class("rest keys service")
// ErrDuplicateKey is error type that occurs when a generated account
// management api key already exists.
@ -32,18 +32,18 @@ var (
ErrInvalidKey = errs.Class("invalid key")
)
// Config contains configuration parameters for account management api keys.
// Config contains configuration parameters for rest keys.
type Config struct {
DefaultExpiration time.Duration `help:"expiration to use if user does not specify an account management api key expiration" default:"720h"`
DefaultExpiration time.Duration `help:"expiration to use if user does not specify an rest key expiration" default:"720h"`
}
// Service handles operations regarding account management api keys.
// Service handles operations regarding rest keys.
type Service struct {
db oidc.OAuthTokens
config Config
}
// NewService creates a new account management api keys service.
// NewService creates a new rest keys service.
func NewService(db oidc.OAuthTokens, config Config) *Service {
return &Service{
db: db,
@ -51,7 +51,7 @@ func NewService(db oidc.OAuthTokens, config Config) *Service {
}
}
// Create creates and inserts an account management api key into the db.
// Create creates and inserts an rest key into the db.
func (s *Service) Create(ctx context.Context, userID uuid.UUID, expiration time.Duration) (apiKey string, expiresAt time.Time, err error) {
defer mon.Task()(&ctx)(&err)
@ -61,7 +61,7 @@ func (s *Service) Create(ctx context.Context, userID uuid.UUID, expiration time.
}
expiresAt, err = s.InsertIntoDB(ctx, oidc.OAuthToken{
UserID: userID,
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: hash,
}, time.Now(), expiration)
if err != nil {
@ -111,7 +111,7 @@ func (s *Service) InsertIntoDB(ctx context.Context, oAuthToken oidc.OAuthToken,
// The token column is the key to the OAuthTokens table, but the Create method does not return an error if a duplicate token insert is attempted.
// We need to make sure a unique api key is created, so check that the value doesn't already exist.
_, err = s.db.Get(ctx, oidc.KindAccountManagementTokenV0, oAuthToken.Token)
_, err = s.db.Get(ctx, oidc.KindRESTTokenV0, oAuthToken.Token)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
return time.Time{}, Error.Wrap(err)
@ -144,7 +144,7 @@ func (s *Service) GetUserAndExpirationFromKey(ctx context.Context, apiKey string
if err != nil {
return uuid.UUID{}, time.Now(), err
}
keyInfo, err := s.db.Get(ctx, oidc.KindAccountManagementTokenV0, hash)
keyInfo, err := s.db.Get(ctx, oidc.KindRESTTokenV0, hash)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return uuid.UUID{}, time.Now(), Error.Wrap(ErrInvalidKey.New("invalid account management api key"))
@ -163,11 +163,11 @@ func (s *Service) Revoke(ctx context.Context, apiKey string) (err error) {
return Error.Wrap(err)
}
_, err = s.db.Get(ctx, oidc.KindAccountManagementTokenV0, hash)
_, err = s.db.Get(ctx, oidc.KindRESTTokenV0, hash)
if err != nil {
return Error.Wrap(err)
}
err = s.db.RevokeAccountManagementTokenV0(ctx, hash)
err = s.db.RevokeRESTTokenV0(ctx, hash)
if err != nil {
return Error.Wrap(err)
}

View File

@ -1,7 +1,7 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package accountmanagementapikeys_test
package restkeys_test
import (
"database/sql"
@ -13,16 +13,16 @@ import (
"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/storj/private/testplanet"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/oidc"
)
func TestAccountManagementAPIKeys(t *testing.T) {
func TestRESTKeys(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
sat := planet.Satellites[0]
service := sat.API.AccountManagementAPIKeys.Service
service := sat.API.REST.Keys
id := testrand.UUID()
now := time.Now()
@ -42,14 +42,14 @@ func TestAccountManagementAPIKeys(t *testing.T) {
require.NoError(t, err)
_, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
UserID: id,
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: hash,
}, now, expires)
require.True(t, accountmanagementapikeys.ErrDuplicateKey.Has(err))
require.True(t, restkeys.ErrDuplicateKey.Has(err))
// test revocation
require.NoError(t, service.Revoke(ctx, apiKey))
token, err := sat.DB.OIDC().OAuthTokens().Get(ctx, oidc.KindAccountManagementTokenV0, hash)
token, err := sat.DB.OIDC().OAuthTokens().Get(ctx, oidc.KindRESTTokenV0, hash)
require.Equal(t, sql.ErrNoRows, err)
require.True(t, token.ExpiresAt.IsZero())
@ -60,41 +60,41 @@ func TestAccountManagementAPIKeys(t *testing.T) {
// test GetUserFromKey non existent key
_, _, err = service.GetUserAndExpirationFromKey(ctx, nonexistent)
require.True(t, accountmanagementapikeys.ErrInvalidKey.Has(err))
require.True(t, restkeys.ErrInvalidKey.Has(err))
})
}
func TestAccountManagementAPIKeysExpiration(t *testing.T) {
func TestRESTKeysExpiration(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
sat := planet.Satellites[0]
service := sat.API.AccountManagementAPIKeys.Service
service := sat.API.REST.Keys
now := time.Now()
// test no expiration uses default
expiresAt, err := service.InsertIntoDB(ctx, oidc.OAuthToken{
UserID: testrand.UUID(),
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: "testhash0",
}, now, 0)
require.NoError(t, err)
require.Equal(t, now.Add(sat.Config.AccountManagementAPIKeys.DefaultExpiration), expiresAt)
require.Equal(t, now.Add(sat.Config.RESTKeys.DefaultExpiration), expiresAt)
// test negative expiration uses default
expiresAt, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
UserID: testrand.UUID(),
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: "testhash1",
}, now, -10000)
require.NoError(t, err)
require.Equal(t, now.Add(sat.Config.AccountManagementAPIKeys.DefaultExpiration), expiresAt)
require.Equal(t, now.Add(sat.Config.RESTKeys.DefaultExpiration), expiresAt)
// test regular expiration
expiration := 14 * time.Hour
expiresAt, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
UserID: testrand.UUID(),
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: "testhash2",
}, now, expiration)
require.NoError(t, err)

View File

@ -104,16 +104,16 @@ var (
type Service struct {
Signer
log, auditLogger *zap.Logger
store DB
accountManagementAPIKeys AccountManagementAPIKeys
projectAccounting accounting.ProjectAccounting
projectUsage *accounting.Service
buckets Buckets
partners *rewards.PartnersService
accounts payments.Accounts
recaptchaHandler RecaptchaHandler
analytics *analytics.Service
log, auditLogger *zap.Logger
store DB
restKeys RESTKeys
projectAccounting accounting.ProjectAccounting
projectUsage *accounting.Service
buckets Buckets
partners *rewards.PartnersService
accounts payments.Accounts
recaptchaHandler RecaptchaHandler
analytics *analytics.Service
config Config
}
@ -154,7 +154,7 @@ type PaymentsService struct {
}
// NewService returns new instance of Service.
func NewService(log *zap.Logger, signer Signer, store DB, accountManagementAPIKeys AccountManagementAPIKeys, projectAccounting accounting.ProjectAccounting, projectUsage *accounting.Service, buckets Buckets, partners *rewards.PartnersService, accounts payments.Accounts, analytics *analytics.Service, config Config) (*Service, error) {
func NewService(log *zap.Logger, signer Signer, store DB, restKeys RESTKeys, projectAccounting accounting.ProjectAccounting, projectUsage *accounting.Service, buckets Buckets, partners *rewards.PartnersService, accounts payments.Accounts, analytics *analytics.Service, config Config) (*Service, error) {
if signer == nil {
return nil, errs.New("signer can't be nil")
}
@ -169,19 +169,19 @@ func NewService(log *zap.Logger, signer Signer, store DB, accountManagementAPIKe
}
return &Service{
log: log,
auditLogger: log.Named("auditlog"),
Signer: signer,
store: store,
accountManagementAPIKeys: accountManagementAPIKeys,
projectAccounting: projectAccounting,
projectUsage: projectUsage,
buckets: buckets,
partners: partners,
accounts: accounts,
recaptchaHandler: NewDefaultRecaptcha(config.Recaptcha.SecretKey),
analytics: analytics,
config: config,
log: log,
auditLogger: log.Named("auditlog"),
Signer: signer,
store: store,
restKeys: restKeys,
projectAccounting: projectAccounting,
projectUsage: projectUsage,
buckets: buckets,
partners: partners,
accounts: accounts,
recaptchaHandler: NewDefaultRecaptcha(config.Recaptcha.SecretKey),
analytics: analytics,
config: config,
}, nil
}
@ -1815,32 +1815,32 @@ func (s *Service) GetAPIKeys(ctx context.Context, projectID uuid.UUID, cursor AP
return
}
// CreateAccountManagementAPIKey creates an account management api key.
func (s *Service) CreateAccountManagementAPIKey(ctx context.Context, expiration time.Duration) (apiKey string, expiresAt time.Time, err error) {
// CreateRESTKey creates a satellite rest key.
func (s *Service) CreateRESTKey(ctx context.Context, expiration time.Duration) (apiKey string, expiresAt time.Time, err error) {
defer mon.Task()(&ctx)(&err)
auth, err := s.getAuthAndAuditLog(ctx, "create account management api key")
auth, err := s.getAuthAndAuditLog(ctx, "create rest key")
if err != nil {
return "", time.Time{}, Error.Wrap(err)
}
apiKey, expiresAt, err = s.accountManagementAPIKeys.Create(ctx, auth.User.ID, expiration)
apiKey, expiresAt, err = s.restKeys.Create(ctx, auth.User.ID, expiration)
if err != nil {
return "", time.Time{}, Error.Wrap(err)
}
return apiKey, expiresAt, nil
}
// RevokeAccountManagementAPIKey revokes an account management api key.
func (s *Service) RevokeAccountManagementAPIKey(ctx context.Context, apiKey string) (err error) {
// RevokeRESTKey revokes a satellite REST key.
func (s *Service) RevokeRESTKey(ctx context.Context, apiKey string) (err error) {
defer mon.Task()(&ctx)(&err)
_, err = s.getAuthAndAuditLog(ctx, "revoke account management api key")
_, err = s.getAuthAndAuditLog(ctx, "revoke rest key")
if err != nil {
return Error.Wrap(err)
}
err = s.accountManagementAPIKeys.Revoke(ctx, apiKey)
err = s.restKeys.Revoke(ctx, apiKey)
if err != nil {
return Error.Wrap(err)
}
@ -2219,7 +2219,7 @@ func (s *Service) keyAuth(ctx context.Context, r *http.Request) (context.Context
ctx = consoleauth.WithAPIKey(ctx, []byte(apikey))
userID, exp, err := s.accountManagementAPIKeys.GetUserAndExpirationFromKey(ctx, apikey)
userID, exp, err := s.restKeys.GetUserAndExpirationFromKey(ctx, apikey)
if err != nil {
return nil, err
}

View File

@ -692,7 +692,7 @@ func TestActivateAccountToken(t *testing.T) {
})
}
func TestAccountManagementAPIKeys(t *testing.T) {
func TestRESTKeys(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
@ -710,18 +710,18 @@ func TestAccountManagementAPIKeys(t *testing.T) {
now := time.Now()
expires := 5 * time.Hour
apiKey, expiresAt, err := service.CreateAccountManagementAPIKey(authCtx, expires)
apiKey, expiresAt, err := service.CreateRESTKey(authCtx, expires)
require.NoError(t, err)
require.NotEmpty(t, apiKey)
require.True(t, expiresAt.After(now))
require.True(t, expiresAt.Before(now.Add(expires+time.Hour)))
// test revocation
require.NoError(t, service.RevokeAccountManagementAPIKey(authCtx, apiKey))
require.NoError(t, service.RevokeRESTKey(authCtx, apiKey))
// test revoke non existent key
nonexistent := testrand.UUID()
err = service.RevokeAccountManagementAPIKey(authCtx, nonexistent.String())
err = service.RevokeRESTKey(authCtx, nonexistent.String())
require.Error(t, err)
})
}

View File

@ -92,8 +92,8 @@ type OAuthTokens interface {
// Create creates a new OAuthToken. If the token already exists, no value is modified and nil is returned.
Create(ctx context.Context, token OAuthToken) error
// RevokeAccountManagementTokenV0 revokes a v0 account management token by setting its expires_at time to zero.
RevokeAccountManagementTokenV0(ctx context.Context, token string) error
// RevokeRESTTokenV0 revokes a v0 rest token by setting its expires_at time to zero.
RevokeRESTTokenV0(ctx context.Context, token string) error
}
// OAuthTokenKind defines an enumeration of different types of supported tokens.
@ -106,8 +106,8 @@ const (
KindAccessToken = 1
// KindRefreshToken represents a refresh token within the database.
KindRefreshToken = 2
// KindAccountManagementTokenV0 represents an account management token within the database.
KindAccountManagementTokenV0 = 3
// KindRESTTokenV0 represents a REST token within the database.
KindRESTTokenV0 = 3
)
// OAuthCode represents a code stored within our database.

View File

@ -181,10 +181,10 @@ func (o *tokensDBX) Create(ctx context.Context, token OAuthToken) error {
return err
}
// RevokeAccountManagementTokenV0 revokes a v0 account management token by setting its expires_at time to zero.
func (o *tokensDBX) RevokeAccountManagementTokenV0(ctx context.Context, token string) error {
// RevokeRESTTokenV0 revokes a v0 REST token by setting its expires_at time to zero.
func (o *tokensDBX) RevokeRESTTokenV0(ctx context.Context, token string) error {
return o.db.UpdateNoReturn_OauthToken_By_Token_And_Kind(ctx, dbx.OauthToken_Token([]byte(token)),
dbx.OauthToken_Kind(int(KindAccountManagementTokenV0)),
dbx.OauthToken_Kind(int(KindRESTTokenV0)),
dbx.OauthToken_Update_Fields{
ExpiresAt: dbx.OauthToken_ExpiresAt(time.Time{}),
})

View File

@ -112,7 +112,7 @@ func TestOAuthTokens(t *testing.T) {
{
ClientID: clientID,
UserID: userID,
Kind: oidc.KindAccountManagementTokenV0,
Kind: oidc.KindRESTTokenV0,
Token: "testToken",
CreatedAt: start,
ExpiresAt: start.Add(time.Hour),
@ -135,14 +135,14 @@ func TestOAuthTokens(t *testing.T) {
}{
{oidc.KindAccessToken, "expired", sql.ErrNoRows},
{oidc.KindRefreshToken, "valid", nil},
{oidc.KindAccountManagementTokenV0, "testToken", nil},
{oidc.KindRESTTokenV0, "testToken", nil},
}
for _, testCase := range testCases {
_, err := tokens.Get(ctx, testCase.kind, testCase.token)
require.Equal(t, testCase.err, err)
if testCase.kind == oidc.KindAccountManagementTokenV0 {
err = tokens.RevokeAccountManagementTokenV0(ctx, testCase.token)
if testCase.kind == oidc.KindRESTTokenV0 {
err = tokens.RevokeRESTTokenV0(ctx, testCase.token)
require.NoError(t, err)
token, err := tokens.Get(ctx, testCase.kind, testCase.token)
require.Equal(t, sql.ErrNoRows, err)

View File

@ -18,8 +18,8 @@ import (
"storj.io/storj/satellite/accounting/live"
"storj.io/storj/satellite/analytics"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/paymentsconfig"
"storj.io/storj/satellite/payments/stripecoinpayments"
@ -78,7 +78,7 @@ func TestSignupCouponCodes(t *testing.T) {
log.Named("console"),
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
db.Console(),
accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.AccountManagementAPIKeys),
restkeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.RESTKeys),
db.ProjectAccounting(),
projectUsage,
sat.API.Buckets.Service,

View File

@ -26,8 +26,8 @@ import (
"storj.io/storj/satellite/buckets"
"storj.io/storj/satellite/compensation"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/accountmanagementapikeys"
"storj.io/storj/satellite/console/consoleweb"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/contact"
"storj.io/storj/satellite/gc"
"storj.io/storj/satellite/gracefulexit"
@ -145,8 +145,8 @@ type Config struct {
Payments paymentsconfig.Config
AccountManagementAPIKeys accountmanagementapikeys.Config
Console consoleweb.Config
RESTKeys restkeys.Config
Console consoleweb.Config
Version version_checker.Config

View File

@ -1,6 +1,3 @@
# expiration to use if user does not specify an account management api key expiration
# account-management-api-keys.default-expiration: 720h0m0s
# admin peer http listening address
# admin.address: ""
@ -781,6 +778,9 @@ identity.key-path: /root/.local/share/storj/identity/satellite/identity.key
# the time period that must pass before suspended nodes will be disqualified
# reputation.suspension-grace-period: 168h0m0s
# expiration to use if user does not specify an rest key expiration
# rest-keys.default-expiration: 720h0m0s
# age at which a rollup is archived
# rollup-archive.archive-age: 2160h0m0s