2019-03-19 17:55:43 +00:00
|
|
|
// Copyright (C) 2018 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package console
|
|
|
|
|
|
|
|
import (
|
2020-03-11 15:36:55 +00:00
|
|
|
"bytes"
|
2019-03-19 17:55:43 +00:00
|
|
|
"context"
|
|
|
|
"crypto/rand"
|
|
|
|
"encoding/base64"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
2020-03-30 10:08:50 +01:00
|
|
|
|
|
|
|
"storj.io/common/uuid"
|
2019-03-19 17:55:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// RegistrationTokens is interface for working with registration tokens
|
2019-09-10 14:24:16 +01:00
|
|
|
//
|
|
|
|
// architecture: Database
|
2019-03-19 17:55:43 +00:00
|
|
|
type RegistrationTokens interface {
|
|
|
|
// Create creates new registration token
|
|
|
|
Create(ctx context.Context, projectLimit int) (*RegistrationToken, error)
|
|
|
|
// GetBySecret retrieves RegTokenInfo with given Secret
|
|
|
|
GetBySecret(ctx context.Context, secret RegistrationSecret) (*RegistrationToken, error)
|
|
|
|
// GetByOwnerID retrieves RegTokenInfo by ownerID
|
|
|
|
GetByOwnerID(ctx context.Context, ownerID uuid.UUID) (*RegistrationToken, error)
|
|
|
|
// UpdateOwner updates registration token's owner
|
|
|
|
UpdateOwner(ctx context.Context, secret RegistrationSecret, ownerID uuid.UUID) error
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegistrationSecret stores secret of registration token
|
|
|
|
type RegistrationSecret [32]byte
|
|
|
|
|
|
|
|
// RegistrationToken describing api key model in the database
|
|
|
|
type RegistrationToken struct {
|
|
|
|
// Secret is PK of the table and keeps unique value forRegToken
|
|
|
|
Secret RegistrationSecret
|
|
|
|
// OwnerID stores current token owner ID
|
|
|
|
OwnerID *uuid.UUID
|
|
|
|
|
|
|
|
// ProjectLimit defines how many projects user is able to create
|
|
|
|
ProjectLimit int `json:"projectLimit"`
|
|
|
|
|
|
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewRegistrationSecret creates new registration secret
|
|
|
|
func NewRegistrationSecret() (RegistrationSecret, error) {
|
|
|
|
var b [32]byte
|
|
|
|
|
|
|
|
_, err := rand.Read(b[:])
|
|
|
|
if err != nil {
|
|
|
|
return b, errs.New("error creating registration secret")
|
|
|
|
}
|
|
|
|
|
|
|
|
return b, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// String implements Stringer
|
|
|
|
func (secret RegistrationSecret) String() string {
|
|
|
|
return base64.URLEncoding.EncodeToString(secret[:])
|
|
|
|
}
|
|
|
|
|
2020-03-11 15:36:55 +00:00
|
|
|
// IsZero returns if the RegistrationSecret is not set
|
|
|
|
func (secret RegistrationSecret) IsZero() bool {
|
|
|
|
var zero RegistrationSecret
|
|
|
|
// this doesn't need to be constant-time, because we're explicitly testing
|
|
|
|
// against a hardcoded, well-known value
|
|
|
|
return bytes.Equal(secret[:], zero[:])
|
|
|
|
}
|
|
|
|
|
2019-03-19 17:55:43 +00:00
|
|
|
// RegistrationSecretFromBase64 creates new registration secret from base64 string
|
|
|
|
func RegistrationSecretFromBase64(s string) (RegistrationSecret, error) {
|
|
|
|
var secret RegistrationSecret
|
|
|
|
|
|
|
|
b, err := base64.URLEncoding.DecodeString(s)
|
|
|
|
if err != nil {
|
|
|
|
return secret, err
|
|
|
|
}
|
|
|
|
|
|
|
|
copy(secret[:], b)
|
|
|
|
|
|
|
|
return secret, nil
|
|
|
|
}
|