The goal of this new database implementation is to make the database more robust by adding a cockrochdb implementation and modifying the database interface and the current leveldb implementation as appropriate.
In order to support cockroachdb the User sensitive data must be encrypted at flight and at rest. It will require a few modifications in the Db design as part of the user information should be public and the rest encrypted.
In order to accomplish that the User struct will be splitted in two other
structs UserDetails
and User
.
UserDetails: contains all the sensitive user data and and it is the part which will be enconded and encrypted before saving into the db
type UserDetails struct {
Email string // Email address + lookup key.
HashedPassword []byte // Blowfish hash
Admin bool // Is user an admin
PaywallAddressIndex uint64 // Sequential id used to generate paywall address
NewUserPaywallAddress string // Address the user needs to send to
NewUserPaywallAmount uint64 // Amount the user needs to send
NewUserPaywallTx string // Paywall transaction id
NewUserPaywallTxNotBefore int64 // Transactions occurring before this time will not be valid.
NewUserPaywallPollExpiry int64 // After this time, the user's paywall address will not be continuously polled
NewUserVerificationToken []byte // New user registration verification token
NewUserVerificationExpiry int64 // New user registration verification expiration
ResendNewUserVerificationExpiry int64 // Resend request for new user registration verification expiration
UpdateKeyVerificationToken []byte // Verification token for updating keypair
UpdateKeyVerificationExpiry int64 // Verification expiration
ResetPasswordVerificationToken []byte // Reset password token
ResetPasswordVerificationExpiry int64 // Reset password token expiration
LastLoginTime int64 // Unix timestamp of when the user last logged in
FailedLoginAttempts uint64 // Number of failed login a user has made in a row
Deactivated bool // Whether the account is deactivated or not
EmailNotifications uint64 // Notify the user via emails
ProposalCommentsAccessTimes map[string]int64
Identities []Identity
ProposalPaywalls []ProposalPaywall
UnspentProposalCredits []ProposalCredit
SpentProposalCredits []ProposalCredit
}
User: contains the public information of the user as well the encrypted blob of UserDetails
type User struct {
ID uuid.UUID // Primary key
Username string // Secoondary key
Payload []byte // Encrypted blob of user details
}
In order to support the changes in the User structure the Db interface will be modified accordingly.
type Database interface {
UserGetByID(uuid.UUID) (string, UserDetails, error) // Returns the requested UserDetails along with the username
UserGetByUsername(string) (uuid.UUID, UserDetails, error) // Returns the requested UserDetails along with the user ID
UserNew(string, UserDetails) error // Creates a new user with the username and details provided
UserUpdate(uuid.UUID, string, UserDetails) // Updates the user details and username if it has changed
Open() error
Close() error
}
Note that the work of encrypting/decrypting the user details is always hidden from the caller of the database interface methods.
User package:
Database: