-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
user: Add cockroachdb interface implementation #856
Conversation
Tested with pi/cms modes and everything seems to be running smooth, no bugs testing all features from my end. Great PR! |
This commit adds a cockroachdb implementation of the user database interface. Some details about the implementation: - Data at rest is encrypted. A few public fields (ID, username, pubkeys) have been pulled out to allow them to be queryable. - politeawww_dbutil has been updated to support the cockroachdb implementation. Commands have been added for creating encryption keys and for migrating an existing user database from leveldb to cockroachdb. - The ability to rotate encryption keys has been added to politeiawww. - The user lookup by email function has been removed from the user database interface. Email is part of the encrypted user data blob and user lookups by email need to be completely phased out of politeiawww. **Further work that will be required** - Switch all user lookups by email in politeia to be user lookups by username or ID. The politeiawww userEmails cache can be removed once this is done. - Remove the politeiawww userPubkeys cache now that the pubkeys are queryable. I'll open issues for these once this PR gets merged.
setting. To rotate keys, set `oldencryptionkey` to the existing key and set | ||
`encryptionkey` to the new key. Starting politeiawww with both of these config | ||
params set will kick off a key rotation. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat but does this re-encrypt the entire db? I ask because what happens if you do this twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it will re-encrypt the entire db. If you do it twice, without changing the config params, it will throw a cannot decrypt
error on the first user it tries to decrypt because the old key is no longer valid.
@@ -827,7 +827,7 @@ func New(user, host, net, rootCert, cert, key string) (*cockroachdb, error) { | |||
// names manually. | |||
c.recordsdb.SingularTable(true) | |||
|
|||
log.Infof("Cache host: %v", h) | |||
log.Infof("Cache host : %v", h) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eew. Don't put a space before the :
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -112,6 +112,7 @@ type politeiawww struct { | |||
test bool | |||
|
|||
// Following entries require locks | |||
// XXX userPubkeys can be removed now that the userdb is queryable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do want to remain compat with leveldb so while it can go away we may have to move this functionality into the db (e.g. make it queriable and maybe add an index)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
politeiawww/user.go
Outdated
@@ -29,10 +29,15 @@ const ( | |||
|
|||
// Route to reset password at GUI | |||
ResetPasswordGuiRoute = "/password" // XXX what is this doing here? | |||
|
|||
emailRegex = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@" + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to use single quotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backticks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. `
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
util/encrypt.go
Outdated
} | ||
|
||
// NewEncryptionKey creates and save a new encryption key at the provided | ||
// filepath. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saves
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
util/encrypt.go
Outdated
@@ -0,0 +1,92 @@ | |||
// Copyright (c) 2017-2019 The Decred developers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keys must always be pointers. You violate that rule in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
util/encrypt.go
Outdated
|
||
// EncryptionKey wraps a 32 byte encryption key and the time when it | ||
// was created. | ||
type EncryptionKey struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a version field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
util/encrypt.go
Outdated
|
||
// Encrypt encrypts a byte slice with the provided version using the | ||
// provided key. | ||
func Encrypt(version uint32, key [32]byte, data []byte) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Key must be a pointer. Alternatively, you could use a target instead of passing the key in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made all keys pointers.
PR is running smooth on my end for Pi and CMS as well! Only part I'm a tad confused about is the usage of localDB vs. levelDB inside of politeiawww_dbutil. I left an inline comment below for this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested and it worked here! I left one small comment regarding the doc example for dev environment.
util/encrypt.go
Outdated
// EncryptionKey wraps a 32 byte encryption key. | ||
type EncryptionKey struct { | ||
Version uint `json:"version"` // Version of this struct | ||
Key *[32]byte `json:"key"` // Key used for encryption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After rereading this, this file needs to go.
Hex encode the key on disk.
When you load it and convert it from hex into a [32]byte slice you return the address to the caller.
Zero out in between copies of the key.
Store key as a pointer in the calling context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Closes #820.
This commit adds a cockroachdb implementation of the user database
interface. Some details about the implementation:
Data at rest is encrypted. A few public fields (ID, username,
pubkeys) have been pulled out to allow them to be queryable.
politeawww_dbutil has been updated to support the cockroachdb
implementation. Commands have been added for creating encryption
keys and for migrating an existing user database from leveldb to
cockroachdb.
The ability to rotate encryption keys has been added to politeiawww.
The user lookup by email function has been removed from the user
database implementation. Email is part of the encrypted user data blob
and user lookups by email need to be completely phased out of
politeiawww.
Further work that will be required
Switch all user lookups by email in politeia to be user lookups by
username or ID. The politeiawww userEmails cache can be removed once
this is done.
Remove the politeiawww userPubkeys cache now that the pubkeys are
queryable.
I'll open issues for these once this PR gets merged.