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:
parent
1ed36e9fea
commit
ed5ebb2527
@ -21,7 +21,7 @@ import (
|
|||||||
"storj.io/storj/private/version/checker"
|
"storj.io/storj/private/version/checker"
|
||||||
"storj.io/storj/satellite/admin"
|
"storj.io/storj/satellite/admin"
|
||||||
"storj.io/storj/satellite/buckets"
|
"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/metabase"
|
||||||
"storj.io/storj/satellite/payments"
|
"storj.io/storj/satellite/payments"
|
||||||
"storj.io/storj/satellite/payments/stripecoinpayments"
|
"storj.io/storj/satellite/payments/stripecoinpayments"
|
||||||
@ -65,8 +65,8 @@ type Admin struct {
|
|||||||
Service *buckets.Service
|
Service *buckets.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountManagementAPIKeys struct {
|
REST struct {
|
||||||
Service *accountmanagementapikeys.Service
|
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)
|
peer.Buckets.Service = buckets.NewService(db.Buckets(), metabaseDB)
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // setup account management api keys
|
{ // setup rest keys
|
||||||
peer.AccountManagementAPIKeys.Service = accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), config.AccountManagementAPIKeys)
|
peer.REST.Keys = restkeys.NewService(db.OIDC().OAuthTokens(), config.RESTKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // setup debug
|
{ // setup debug
|
||||||
@ -173,7 +173,7 @@ func NewAdmin(log *zap.Logger, full *identity.FullIdentity, db DB, metabaseDB *m
|
|||||||
adminConfig := config.Admin
|
adminConfig := config.Admin
|
||||||
adminConfig.AuthorizationToken = config.Console.AuthToken
|
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{
|
peer.Servers.Add(lifecycle.Item{
|
||||||
Name: "admin",
|
Name: "admin",
|
||||||
Run: peer.Admin.Server.Run,
|
Run: peer.Admin.Server.Run,
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"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()
|
ctx := r.Context()
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
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 {
|
if err != nil {
|
||||||
sendJSONError(w, "api key creation failed",
|
sendJSONError(w, "api key creation failed",
|
||||||
err.Error(), http.StatusInternalServerError)
|
err.Error(), http.StatusInternalServerError)
|
||||||
@ -91,7 +91,7 @@ func (server *Server) addAccountManagementAPIKey(w http.ResponseWriter, r *http.
|
|||||||
sendJSONData(w, http.StatusOK, data)
|
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()
|
ctx := r.Context()
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
@ -102,7 +102,7 @@ func (server *Server) revokeAccountManagementAPIKey(w http.ResponseWriter, r *ht
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.accountManagementAPIKeys.Revoke(ctx, apiKey)
|
err := server.restKeys.Revoke(ctx, apiKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendJSONError(w, "failed to revoke api key",
|
sendJSONError(w, "failed to revoke api key",
|
||||||
err.Error(), http.StatusNotFound)
|
err.Error(), http.StatusNotFound)
|
@ -22,7 +22,7 @@ import (
|
|||||||
"storj.io/storj/satellite/oidc"
|
"storj.io/storj/satellite/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccountManagementAPIKeys(t *testing.T) {
|
func TestRESTKeys(t *testing.T) {
|
||||||
testplanet.Run(t, testplanet.Config{
|
testplanet.Run(t, testplanet.Config{
|
||||||
SatelliteCount: 1,
|
SatelliteCount: 1,
|
||||||
StorageNodeCount: 0,
|
StorageNodeCount: 0,
|
||||||
@ -35,14 +35,14 @@ func TestAccountManagementAPIKeys(t *testing.T) {
|
|||||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
address := planet.Satellites[0].Admin.Admin.Listener.Addr()
|
address := planet.Satellites[0].Admin.Admin.Listener.Addr()
|
||||||
satellite := planet.Satellites[0]
|
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)
|
user, err := planet.Satellites[0].DB.Console().Users().GetByEmail(ctx, planet.Uplinks[0].Projects[0].Owner.Email)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
t.Run("create with default expiration", func(t *testing.T) {
|
t.Run("create with default expiration", func(t *testing.T) {
|
||||||
body := strings.NewReader(`{"expiration":""}`)
|
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)
|
require.NoError(t, err)
|
||||||
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
|
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ func TestAccountManagementAPIKeys(t *testing.T) {
|
|||||||
require.False(t, exp.Before(now))
|
require.False(t, exp.Before(now))
|
||||||
|
|
||||||
// check the expiration is around the time we expect
|
// 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.After(now.Add(defaultExpiration)))
|
||||||
require.True(t, output.ExpiresAt.Before(now.Add(defaultExpiration+time.Hour)))
|
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) {
|
t.Run("create with custom expiration", func(t *testing.T) {
|
||||||
durationString := "3h"
|
durationString := "3h"
|
||||||
body := strings.NewReader(fmt.Sprintf(`{"expiration":"%s"}`, durationString))
|
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)
|
require.NoError(t, err)
|
||||||
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
|
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
|
||||||
|
|
||||||
@ -125,13 +125,13 @@ func TestAccountManagementAPIKeys(t *testing.T) {
|
|||||||
|
|
||||||
expiresAt, err := keyService.InsertIntoDB(ctx, oidc.OAuthToken{
|
expiresAt, err := keyService.InsertIntoDB(ctx, oidc.OAuthToken{
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: hash,
|
Token: hash,
|
||||||
}, time.Now(), time.Hour)
|
}, time.Now(), time.Hour)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, expiresAt.IsZero())
|
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)
|
require.NoError(t, err)
|
||||||
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
|
req.Header.Set("Authorization", satellite.Config.Console.AuthToken)
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
|||||||
adminui "storj.io/storj/satellite/admin/ui"
|
adminui "storj.io/storj/satellite/admin/ui"
|
||||||
"storj.io/storj/satellite/buckets"
|
"storj.io/storj/satellite/buckets"
|
||||||
"storj.io/storj/satellite/console"
|
"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/oidc"
|
||||||
"storj.io/storj/satellite/payments"
|
"storj.io/storj/satellite/payments"
|
||||||
"storj.io/storj/satellite/payments/stripecoinpayments"
|
"storj.io/storj/satellite/payments/stripecoinpayments"
|
||||||
@ -59,7 +59,7 @@ type Server struct {
|
|||||||
db DB
|
db DB
|
||||||
payments payments.Accounts
|
payments payments.Accounts
|
||||||
buckets *buckets.Service
|
buckets *buckets.Service
|
||||||
accountManagementAPIKeys *accountmanagementapikeys.Service
|
restKeys *restkeys.Service
|
||||||
|
|
||||||
nowFn func() time.Time
|
nowFn func() time.Time
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewServer returns a new administration Server.
|
// 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{
|
server := &Server{
|
||||||
log: log,
|
log: log,
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ func NewServer(log *zap.Logger, listener net.Listener, db DB, buckets *buckets.S
|
|||||||
db: db,
|
db: db,
|
||||||
payments: accounts,
|
payments: accounts,
|
||||||
buckets: buckets,
|
buckets: buckets,
|
||||||
accountManagementAPIKeys: accountManagementAPIKeys,
|
restKeys: restKeys,
|
||||||
|
|
||||||
nowFn: time.Now,
|
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.createGeofenceForBucket).Methods("POST")
|
||||||
api.HandleFunc("/projects/{project}/buckets/{bucket}/geofence", server.deleteGeofenceForBucket).Methods("DELETE")
|
api.HandleFunc("/projects/{project}/buckets/{bucket}/geofence", server.deleteGeofenceForBucket).Methods("DELETE")
|
||||||
api.HandleFunc("/apikeys/{apikey}", server.deleteAPIKey).Methods("DELETE")
|
api.HandleFunc("/apikeys/{apikey}", server.deleteAPIKey).Methods("DELETE")
|
||||||
api.HandleFunc("/accountmanagementapikeys/{useremail}", server.addAccountManagementAPIKey).Methods("POST")
|
api.HandleFunc("/restkeys/{useremail}", server.addRESTKey).Methods("POST")
|
||||||
api.HandleFunc("/accountmanagementapikeys/{apikey}/revoke", server.revokeAccountManagementAPIKey).Methods("PUT")
|
api.HandleFunc("/restkeys/{apikey}/revoke", server.revokeRESTKey).Methods("PUT")
|
||||||
|
|
||||||
// This handler must be the last one because it uses the root as prefix,
|
// 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.
|
// otherwise will try to serve all the handlers set after this one.
|
||||||
|
@ -372,28 +372,28 @@ Blank fields will not be updated.`,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
account_management_api_keys: [
|
rest_api_keys: [
|
||||||
{
|
{
|
||||||
name: 'create',
|
name: 'create',
|
||||||
desc: 'Create an account management API key',
|
desc: 'Create a REST key',
|
||||||
//params: [['API key', new InputText('text', true)]],
|
//params: [['API key', new InputText('text', true)]],
|
||||||
params: [
|
params: [
|
||||||
["user's email", new InputText('text', true)],
|
["user's email", new InputText('text', true)],
|
||||||
['expiration', new InputText('text', false)]
|
['expiration', new InputText('text', false)]
|
||||||
],
|
],
|
||||||
func: async (useremail: string, expiration?: string): Promise<Record<string, unknown>> => {
|
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
|
expiration
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'revoke',
|
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)]],
|
||||||
params: [['api key', new InputText('text', true)]],
|
params: [['api key', new InputText('text', true)]],
|
||||||
func: async (apikey: string): Promise<Record<string, unknown>> => {
|
func: async (apikey: string): Promise<Record<string, unknown>> => {
|
||||||
return this.fetch('PUT', `accountmanagementapikeys/${apikey}/revoke`);
|
return this.fetch('PUT', `restkeys/${apikey}/revoke`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -34,9 +34,9 @@ import (
|
|||||||
"storj.io/storj/satellite/analytics"
|
"storj.io/storj/satellite/analytics"
|
||||||
"storj.io/storj/satellite/buckets"
|
"storj.io/storj/satellite/buckets"
|
||||||
"storj.io/storj/satellite/console"
|
"storj.io/storj/satellite/console"
|
||||||
"storj.io/storj/satellite/console/accountmanagementapikeys"
|
|
||||||
"storj.io/storj/satellite/console/consoleauth"
|
"storj.io/storj/satellite/console/consoleauth"
|
||||||
"storj.io/storj/satellite/console/consoleweb"
|
"storj.io/storj/satellite/console/consoleweb"
|
||||||
|
"storj.io/storj/satellite/console/restkeys"
|
||||||
"storj.io/storj/satellite/contact"
|
"storj.io/storj/satellite/contact"
|
||||||
"storj.io/storj/satellite/gracefulexit"
|
"storj.io/storj/satellite/gracefulexit"
|
||||||
"storj.io/storj/satellite/inspector"
|
"storj.io/storj/satellite/inspector"
|
||||||
@ -137,8 +137,8 @@ type API struct {
|
|||||||
Stripe stripecoinpayments.StripeClient
|
Stripe stripecoinpayments.StripeClient
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountManagementAPIKeys struct {
|
REST struct {
|
||||||
Service *accountmanagementapikeys.Service
|
Keys *restkeys.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
Console struct {
|
Console struct {
|
||||||
@ -578,7 +578,7 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ // setup account management api keys
|
{ // 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
|
{ // setup console
|
||||||
@ -595,7 +595,7 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
|
|||||||
peer.Log.Named("console:service"),
|
peer.Log.Named("console:service"),
|
||||||
&consoleauth.Hmac{Secret: []byte(consoleConfig.AuthTokenSecret)},
|
&consoleauth.Hmac{Secret: []byte(consoleConfig.AuthTokenSecret)},
|
||||||
peer.DB.Console(),
|
peer.DB.Console(),
|
||||||
peer.AccountManagementAPIKeys.Service,
|
peer.REST.Keys,
|
||||||
peer.DB.ProjectAccounting(),
|
peer.DB.ProjectAccounting(),
|
||||||
peer.Accounting.ProjectUsage,
|
peer.Accounting.ProjectUsage,
|
||||||
peer.Buckets.Service,
|
peer.Buckets.Service,
|
||||||
|
@ -30,8 +30,8 @@ type APIKeys interface {
|
|||||||
Delete(ctx context.Context, id uuid.UUID) error
|
Delete(ctx context.Context, id uuid.UUID) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountManagementAPIKeys is an interface for account management api key operations.
|
// RESTKeys is an interface for rest key operations.
|
||||||
type AccountManagementAPIKeys interface {
|
type RESTKeys interface {
|
||||||
Create(ctx context.Context, userID uuid.UUID, expiration time.Duration) (apiKey string, expiresAt time.Time, err error)
|
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)
|
GetUserAndExpirationFromKey(ctx context.Context, apiKey string) (userID uuid.UUID, exp time.Time, err error)
|
||||||
Revoke(ctx context.Context, apiKey string) (err error)
|
Revoke(ctx context.Context, apiKey string) (err error)
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// definition for REST API
|
||||||
a := &apigen.API{
|
a := &apigen.API{
|
||||||
Version: "v0",
|
Version: "v0",
|
||||||
Description: "",
|
Description: "",
|
||||||
|
@ -24,9 +24,9 @@ import (
|
|||||||
"storj.io/storj/satellite/accounting/live"
|
"storj.io/storj/satellite/accounting/live"
|
||||||
"storj.io/storj/satellite/analytics"
|
"storj.io/storj/satellite/analytics"
|
||||||
"storj.io/storj/satellite/console"
|
"storj.io/storj/satellite/console"
|
||||||
"storj.io/storj/satellite/console/accountmanagementapikeys"
|
|
||||||
"storj.io/storj/satellite/console/consoleauth"
|
"storj.io/storj/satellite/console/consoleauth"
|
||||||
"storj.io/storj/satellite/console/consoleweb/consoleql"
|
"storj.io/storj/satellite/console/consoleweb/consoleql"
|
||||||
|
"storj.io/storj/satellite/console/restkeys"
|
||||||
"storj.io/storj/satellite/mailservice"
|
"storj.io/storj/satellite/mailservice"
|
||||||
"storj.io/storj/satellite/payments"
|
"storj.io/storj/satellite/payments"
|
||||||
"storj.io/storj/satellite/payments/paymentsconfig"
|
"storj.io/storj/satellite/payments/paymentsconfig"
|
||||||
@ -99,7 +99,7 @@ func TestGraphqlMutation(t *testing.T) {
|
|||||||
log.Named("console"),
|
log.Named("console"),
|
||||||
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
|
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
|
||||||
db.Console(),
|
db.Console(),
|
||||||
accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.AccountManagementAPIKeys),
|
restkeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.RESTKeys),
|
||||||
db.ProjectAccounting(),
|
db.ProjectAccounting(),
|
||||||
projectUsage,
|
projectUsage,
|
||||||
sat.API.Buckets.Service,
|
sat.API.Buckets.Service,
|
||||||
|
@ -21,9 +21,9 @@ import (
|
|||||||
"storj.io/storj/satellite/accounting/live"
|
"storj.io/storj/satellite/accounting/live"
|
||||||
"storj.io/storj/satellite/analytics"
|
"storj.io/storj/satellite/analytics"
|
||||||
"storj.io/storj/satellite/console"
|
"storj.io/storj/satellite/console"
|
||||||
"storj.io/storj/satellite/console/accountmanagementapikeys"
|
|
||||||
"storj.io/storj/satellite/console/consoleauth"
|
"storj.io/storj/satellite/console/consoleauth"
|
||||||
"storj.io/storj/satellite/console/consoleweb/consoleql"
|
"storj.io/storj/satellite/console/consoleweb/consoleql"
|
||||||
|
"storj.io/storj/satellite/console/restkeys"
|
||||||
"storj.io/storj/satellite/mailservice"
|
"storj.io/storj/satellite/mailservice"
|
||||||
"storj.io/storj/satellite/payments"
|
"storj.io/storj/satellite/payments"
|
||||||
"storj.io/storj/satellite/payments/paymentsconfig"
|
"storj.io/storj/satellite/payments/paymentsconfig"
|
||||||
@ -83,7 +83,7 @@ func TestGraphqlQuery(t *testing.T) {
|
|||||||
log.Named("console"),
|
log.Named("console"),
|
||||||
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
|
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
|
||||||
db.Console(),
|
db.Console(),
|
||||||
accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.AccountManagementAPIKeys),
|
restkeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.RESTKeys),
|
||||||
db.ProjectAccounting(),
|
db.ProjectAccounting(),
|
||||||
projectUsage,
|
projectUsage,
|
||||||
sat.API.Buckets.Service,
|
sat.API.Buckets.Service,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (C) 2022 Storj Labs, Inc.
|
// Copyright (C) 2022 Storj Labs, Inc.
|
||||||
// See LICENSE for copying information.
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
package accountmanagementapikeys
|
package restkeys
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -20,8 +20,8 @@ import (
|
|||||||
var mon = monkit.Package()
|
var mon = monkit.Package()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Error describes internal account management api keys error.
|
// Error describes internal rest keys error.
|
||||||
Error = errs.Class("account management api keys service")
|
Error = errs.Class("rest keys service")
|
||||||
|
|
||||||
// ErrDuplicateKey is error type that occurs when a generated account
|
// ErrDuplicateKey is error type that occurs when a generated account
|
||||||
// management api key already exists.
|
// management api key already exists.
|
||||||
@ -32,18 +32,18 @@ var (
|
|||||||
ErrInvalidKey = errs.Class("invalid key")
|
ErrInvalidKey = errs.Class("invalid key")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config contains configuration parameters for account management api keys.
|
// Config contains configuration parameters for rest keys.
|
||||||
type Config struct {
|
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 {
|
type Service struct {
|
||||||
db oidc.OAuthTokens
|
db oidc.OAuthTokens
|
||||||
config Config
|
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 {
|
func NewService(db oidc.OAuthTokens, config Config) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
db: db,
|
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) {
|
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)
|
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{
|
expiresAt, err = s.InsertIntoDB(ctx, oidc.OAuthToken{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: hash,
|
Token: hash,
|
||||||
}, time.Now(), expiration)
|
}, time.Now(), expiration)
|
||||||
if err != nil {
|
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.
|
// 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.
|
// 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 err != nil {
|
||||||
if !errors.Is(err, sql.ErrNoRows) {
|
if !errors.Is(err, sql.ErrNoRows) {
|
||||||
return time.Time{}, Error.Wrap(err)
|
return time.Time{}, Error.Wrap(err)
|
||||||
@ -144,7 +144,7 @@ func (s *Service) GetUserAndExpirationFromKey(ctx context.Context, apiKey string
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return uuid.UUID{}, time.Now(), err
|
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 err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return uuid.UUID{}, time.Now(), Error.Wrap(ErrInvalidKey.New("invalid account management api key"))
|
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)
|
return Error.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.db.Get(ctx, oidc.KindAccountManagementTokenV0, hash)
|
_, err = s.db.Get(ctx, oidc.KindRESTTokenV0, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Error.Wrap(err)
|
return Error.Wrap(err)
|
||||||
}
|
}
|
||||||
err = s.db.RevokeAccountManagementTokenV0(ctx, hash)
|
err = s.db.RevokeRESTTokenV0(ctx, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Error.Wrap(err)
|
return Error.Wrap(err)
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (C) 2020 Storj Labs, Inc.
|
// Copyright (C) 2020 Storj Labs, Inc.
|
||||||
// See LICENSE for copying information.
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
package accountmanagementapikeys_test
|
package restkeys_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
@ -13,16 +13,16 @@ import (
|
|||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/common/testrand"
|
"storj.io/common/testrand"
|
||||||
"storj.io/storj/private/testplanet"
|
"storj.io/storj/private/testplanet"
|
||||||
"storj.io/storj/satellite/console/accountmanagementapikeys"
|
"storj.io/storj/satellite/console/restkeys"
|
||||||
"storj.io/storj/satellite/oidc"
|
"storj.io/storj/satellite/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccountManagementAPIKeys(t *testing.T) {
|
func TestRESTKeys(t *testing.T) {
|
||||||
testplanet.Run(t, testplanet.Config{
|
testplanet.Run(t, testplanet.Config{
|
||||||
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
||||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
sat := planet.Satellites[0]
|
sat := planet.Satellites[0]
|
||||||
service := sat.API.AccountManagementAPIKeys.Service
|
service := sat.API.REST.Keys
|
||||||
|
|
||||||
id := testrand.UUID()
|
id := testrand.UUID()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -42,14 +42,14 @@ func TestAccountManagementAPIKeys(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
|
_, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
|
||||||
UserID: id,
|
UserID: id,
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: hash,
|
Token: hash,
|
||||||
}, now, expires)
|
}, now, expires)
|
||||||
require.True(t, accountmanagementapikeys.ErrDuplicateKey.Has(err))
|
require.True(t, restkeys.ErrDuplicateKey.Has(err))
|
||||||
|
|
||||||
// test revocation
|
// test revocation
|
||||||
require.NoError(t, service.Revoke(ctx, apiKey))
|
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.Equal(t, sql.ErrNoRows, err)
|
||||||
require.True(t, token.ExpiresAt.IsZero())
|
require.True(t, token.ExpiresAt.IsZero())
|
||||||
|
|
||||||
@ -60,41 +60,41 @@ func TestAccountManagementAPIKeys(t *testing.T) {
|
|||||||
|
|
||||||
// test GetUserFromKey non existent key
|
// test GetUserFromKey non existent key
|
||||||
_, _, err = service.GetUserAndExpirationFromKey(ctx, nonexistent)
|
_, _, 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{
|
testplanet.Run(t, testplanet.Config{
|
||||||
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
||||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
sat := planet.Satellites[0]
|
sat := planet.Satellites[0]
|
||||||
service := sat.API.AccountManagementAPIKeys.Service
|
service := sat.API.REST.Keys
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
// test no expiration uses default
|
// test no expiration uses default
|
||||||
expiresAt, err := service.InsertIntoDB(ctx, oidc.OAuthToken{
|
expiresAt, err := service.InsertIntoDB(ctx, oidc.OAuthToken{
|
||||||
UserID: testrand.UUID(),
|
UserID: testrand.UUID(),
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: "testhash0",
|
Token: "testhash0",
|
||||||
}, now, 0)
|
}, now, 0)
|
||||||
require.NoError(t, err)
|
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
|
// test negative expiration uses default
|
||||||
expiresAt, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
|
expiresAt, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
|
||||||
UserID: testrand.UUID(),
|
UserID: testrand.UUID(),
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: "testhash1",
|
Token: "testhash1",
|
||||||
}, now, -10000)
|
}, now, -10000)
|
||||||
require.NoError(t, err)
|
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
|
// test regular expiration
|
||||||
expiration := 14 * time.Hour
|
expiration := 14 * time.Hour
|
||||||
expiresAt, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
|
expiresAt, err = service.InsertIntoDB(ctx, oidc.OAuthToken{
|
||||||
UserID: testrand.UUID(),
|
UserID: testrand.UUID(),
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: "testhash2",
|
Token: "testhash2",
|
||||||
}, now, expiration)
|
}, now, expiration)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
@ -106,7 +106,7 @@ type Service struct {
|
|||||||
|
|
||||||
log, auditLogger *zap.Logger
|
log, auditLogger *zap.Logger
|
||||||
store DB
|
store DB
|
||||||
accountManagementAPIKeys AccountManagementAPIKeys
|
restKeys RESTKeys
|
||||||
projectAccounting accounting.ProjectAccounting
|
projectAccounting accounting.ProjectAccounting
|
||||||
projectUsage *accounting.Service
|
projectUsage *accounting.Service
|
||||||
buckets Buckets
|
buckets Buckets
|
||||||
@ -154,7 +154,7 @@ type PaymentsService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewService returns new instance of Service.
|
// 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 {
|
if signer == nil {
|
||||||
return nil, errs.New("signer can't be nil")
|
return nil, errs.New("signer can't be nil")
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ func NewService(log *zap.Logger, signer Signer, store DB, accountManagementAPIKe
|
|||||||
auditLogger: log.Named("auditlog"),
|
auditLogger: log.Named("auditlog"),
|
||||||
Signer: signer,
|
Signer: signer,
|
||||||
store: store,
|
store: store,
|
||||||
accountManagementAPIKeys: accountManagementAPIKeys,
|
restKeys: restKeys,
|
||||||
projectAccounting: projectAccounting,
|
projectAccounting: projectAccounting,
|
||||||
projectUsage: projectUsage,
|
projectUsage: projectUsage,
|
||||||
buckets: buckets,
|
buckets: buckets,
|
||||||
@ -1815,32 +1815,32 @@ func (s *Service) GetAPIKeys(ctx context.Context, projectID uuid.UUID, cursor AP
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAccountManagementAPIKey creates an account management api key.
|
// CreateRESTKey creates a satellite rest key.
|
||||||
func (s *Service) CreateAccountManagementAPIKey(ctx context.Context, expiration time.Duration) (apiKey string, expiresAt time.Time, err error) {
|
func (s *Service) CreateRESTKey(ctx context.Context, expiration time.Duration) (apiKey string, expiresAt time.Time, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
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 {
|
if err != nil {
|
||||||
return "", time.Time{}, Error.Wrap(err)
|
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 {
|
if err != nil {
|
||||||
return "", time.Time{}, Error.Wrap(err)
|
return "", time.Time{}, Error.Wrap(err)
|
||||||
}
|
}
|
||||||
return apiKey, expiresAt, nil
|
return apiKey, expiresAt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevokeAccountManagementAPIKey revokes an account management api key.
|
// RevokeRESTKey revokes a satellite REST key.
|
||||||
func (s *Service) RevokeAccountManagementAPIKey(ctx context.Context, apiKey string) (err error) {
|
func (s *Service) RevokeRESTKey(ctx context.Context, apiKey string) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
_, err = s.getAuthAndAuditLog(ctx, "revoke account management api key")
|
_, err = s.getAuthAndAuditLog(ctx, "revoke rest key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Error.Wrap(err)
|
return Error.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.accountManagementAPIKeys.Revoke(ctx, apiKey)
|
err = s.restKeys.Revoke(ctx, apiKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Error.Wrap(err)
|
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))
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -692,7 +692,7 @@ func TestActivateAccountToken(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccountManagementAPIKeys(t *testing.T) {
|
func TestRESTKeys(t *testing.T) {
|
||||||
testplanet.Run(t, testplanet.Config{
|
testplanet.Run(t, testplanet.Config{
|
||||||
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
||||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
@ -710,18 +710,18 @@ func TestAccountManagementAPIKeys(t *testing.T) {
|
|||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
expires := 5 * time.Hour
|
expires := 5 * time.Hour
|
||||||
apiKey, expiresAt, err := service.CreateAccountManagementAPIKey(authCtx, expires)
|
apiKey, expiresAt, err := service.CreateRESTKey(authCtx, expires)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, apiKey)
|
require.NotEmpty(t, apiKey)
|
||||||
require.True(t, expiresAt.After(now))
|
require.True(t, expiresAt.After(now))
|
||||||
require.True(t, expiresAt.Before(now.Add(expires+time.Hour)))
|
require.True(t, expiresAt.Before(now.Add(expires+time.Hour)))
|
||||||
|
|
||||||
// test revocation
|
// test revocation
|
||||||
require.NoError(t, service.RevokeAccountManagementAPIKey(authCtx, apiKey))
|
require.NoError(t, service.RevokeRESTKey(authCtx, apiKey))
|
||||||
|
|
||||||
// test revoke non existent key
|
// test revoke non existent key
|
||||||
nonexistent := testrand.UUID()
|
nonexistent := testrand.UUID()
|
||||||
err = service.RevokeAccountManagementAPIKey(authCtx, nonexistent.String())
|
err = service.RevokeRESTKey(authCtx, nonexistent.String())
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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 creates a new OAuthToken. If the token already exists, no value is modified and nil is returned.
|
||||||
Create(ctx context.Context, token OAuthToken) error
|
Create(ctx context.Context, token OAuthToken) error
|
||||||
|
|
||||||
// RevokeAccountManagementTokenV0 revokes a v0 account management token by setting its expires_at time to zero.
|
// RevokeRESTTokenV0 revokes a v0 rest token by setting its expires_at time to zero.
|
||||||
RevokeAccountManagementTokenV0(ctx context.Context, token string) error
|
RevokeRESTTokenV0(ctx context.Context, token string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// OAuthTokenKind defines an enumeration of different types of supported tokens.
|
// OAuthTokenKind defines an enumeration of different types of supported tokens.
|
||||||
@ -106,8 +106,8 @@ const (
|
|||||||
KindAccessToken = 1
|
KindAccessToken = 1
|
||||||
// KindRefreshToken represents a refresh token within the database.
|
// KindRefreshToken represents a refresh token within the database.
|
||||||
KindRefreshToken = 2
|
KindRefreshToken = 2
|
||||||
// KindAccountManagementTokenV0 represents an account management token within the database.
|
// KindRESTTokenV0 represents a REST token within the database.
|
||||||
KindAccountManagementTokenV0 = 3
|
KindRESTTokenV0 = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuthCode represents a code stored within our database.
|
// OAuthCode represents a code stored within our database.
|
||||||
|
@ -181,10 +181,10 @@ func (o *tokensDBX) Create(ctx context.Context, token OAuthToken) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevokeAccountManagementTokenV0 revokes a v0 account management token by setting its expires_at time to zero.
|
// RevokeRESTTokenV0 revokes a v0 REST token by setting its expires_at time to zero.
|
||||||
func (o *tokensDBX) RevokeAccountManagementTokenV0(ctx context.Context, token string) error {
|
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)),
|
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{
|
dbx.OauthToken_Update_Fields{
|
||||||
ExpiresAt: dbx.OauthToken_ExpiresAt(time.Time{}),
|
ExpiresAt: dbx.OauthToken_ExpiresAt(time.Time{}),
|
||||||
})
|
})
|
||||||
|
@ -112,7 +112,7 @@ func TestOAuthTokens(t *testing.T) {
|
|||||||
{
|
{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Kind: oidc.KindAccountManagementTokenV0,
|
Kind: oidc.KindRESTTokenV0,
|
||||||
Token: "testToken",
|
Token: "testToken",
|
||||||
CreatedAt: start,
|
CreatedAt: start,
|
||||||
ExpiresAt: start.Add(time.Hour),
|
ExpiresAt: start.Add(time.Hour),
|
||||||
@ -135,14 +135,14 @@ func TestOAuthTokens(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{oidc.KindAccessToken, "expired", sql.ErrNoRows},
|
{oidc.KindAccessToken, "expired", sql.ErrNoRows},
|
||||||
{oidc.KindRefreshToken, "valid", nil},
|
{oidc.KindRefreshToken, "valid", nil},
|
||||||
{oidc.KindAccountManagementTokenV0, "testToken", nil},
|
{oidc.KindRESTTokenV0, "testToken", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
_, err := tokens.Get(ctx, testCase.kind, testCase.token)
|
_, err := tokens.Get(ctx, testCase.kind, testCase.token)
|
||||||
require.Equal(t, testCase.err, err)
|
require.Equal(t, testCase.err, err)
|
||||||
if testCase.kind == oidc.KindAccountManagementTokenV0 {
|
if testCase.kind == oidc.KindRESTTokenV0 {
|
||||||
err = tokens.RevokeAccountManagementTokenV0(ctx, testCase.token)
|
err = tokens.RevokeRESTTokenV0(ctx, testCase.token)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
token, err := tokens.Get(ctx, testCase.kind, testCase.token)
|
token, err := tokens.Get(ctx, testCase.kind, testCase.token)
|
||||||
require.Equal(t, sql.ErrNoRows, err)
|
require.Equal(t, sql.ErrNoRows, err)
|
||||||
|
@ -18,8 +18,8 @@ import (
|
|||||||
"storj.io/storj/satellite/accounting/live"
|
"storj.io/storj/satellite/accounting/live"
|
||||||
"storj.io/storj/satellite/analytics"
|
"storj.io/storj/satellite/analytics"
|
||||||
"storj.io/storj/satellite/console"
|
"storj.io/storj/satellite/console"
|
||||||
"storj.io/storj/satellite/console/accountmanagementapikeys"
|
|
||||||
"storj.io/storj/satellite/console/consoleauth"
|
"storj.io/storj/satellite/console/consoleauth"
|
||||||
|
"storj.io/storj/satellite/console/restkeys"
|
||||||
"storj.io/storj/satellite/payments"
|
"storj.io/storj/satellite/payments"
|
||||||
"storj.io/storj/satellite/payments/paymentsconfig"
|
"storj.io/storj/satellite/payments/paymentsconfig"
|
||||||
"storj.io/storj/satellite/payments/stripecoinpayments"
|
"storj.io/storj/satellite/payments/stripecoinpayments"
|
||||||
@ -78,7 +78,7 @@ func TestSignupCouponCodes(t *testing.T) {
|
|||||||
log.Named("console"),
|
log.Named("console"),
|
||||||
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
|
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
|
||||||
db.Console(),
|
db.Console(),
|
||||||
accountmanagementapikeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.AccountManagementAPIKeys),
|
restkeys.NewService(db.OIDC().OAuthTokens(), planet.Satellites[0].Config.RESTKeys),
|
||||||
db.ProjectAccounting(),
|
db.ProjectAccounting(),
|
||||||
projectUsage,
|
projectUsage,
|
||||||
sat.API.Buckets.Service,
|
sat.API.Buckets.Service,
|
||||||
|
@ -26,8 +26,8 @@ import (
|
|||||||
"storj.io/storj/satellite/buckets"
|
"storj.io/storj/satellite/buckets"
|
||||||
"storj.io/storj/satellite/compensation"
|
"storj.io/storj/satellite/compensation"
|
||||||
"storj.io/storj/satellite/console"
|
"storj.io/storj/satellite/console"
|
||||||
"storj.io/storj/satellite/console/accountmanagementapikeys"
|
|
||||||
"storj.io/storj/satellite/console/consoleweb"
|
"storj.io/storj/satellite/console/consoleweb"
|
||||||
|
"storj.io/storj/satellite/console/restkeys"
|
||||||
"storj.io/storj/satellite/contact"
|
"storj.io/storj/satellite/contact"
|
||||||
"storj.io/storj/satellite/gc"
|
"storj.io/storj/satellite/gc"
|
||||||
"storj.io/storj/satellite/gracefulexit"
|
"storj.io/storj/satellite/gracefulexit"
|
||||||
@ -145,7 +145,7 @@ type Config struct {
|
|||||||
|
|
||||||
Payments paymentsconfig.Config
|
Payments paymentsconfig.Config
|
||||||
|
|
||||||
AccountManagementAPIKeys accountmanagementapikeys.Config
|
RESTKeys restkeys.Config
|
||||||
Console consoleweb.Config
|
Console consoleweb.Config
|
||||||
|
|
||||||
Version version_checker.Config
|
Version version_checker.Config
|
||||||
|
6
scripts/testdata/satellite-config.yaml.lock
vendored
6
scripts/testdata/satellite-config.yaml.lock
vendored
@ -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 peer http listening address
|
||||||
# admin.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
|
# the time period that must pass before suspended nodes will be disqualified
|
||||||
# reputation.suspension-grace-period: 168h0m0s
|
# 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
|
# age at which a rollup is archived
|
||||||
# rollup-archive.archive-age: 2160h0m0s
|
# rollup-archive.archive-age: 2160h0m0s
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user