add name/id and consolidate webauthn types in model/table

so we can be in line with what the admin handles, and keep it simple on
the api side and do as little manipulation of binary data as possible.

### Minor changes

* id is a UUID we can use for referencing within notify. No relation to
 the key itself.
* name is a user viewable name that can be set/edited
* fix updated_at to have onupdate, not default

### Simplify the webauthn data

credential_data is the data we store about an authenticator that we'll
use to identify the key when logging in. includes the credential_id, the
public_key, and the aaguid (which identifies the authenticator
make/model)

registration_response is the data containing audit information - in the
future we can use this to ensure that the authenticators used are of
high quality.

both of these fields are CBOR (a kind of binary json), encoded in
base64 so that they can be embedded within our regular JSON api
endpoints. we don't anticipate the api ever needing to interact with
this data directly.
This commit is contained in:
Leo Hemsted
2021-05-10 16:36:00 +01:00
parent 3798a3bd1d
commit 500feba50d
2 changed files with 20 additions and 17 deletions

View File

@@ -2600,13 +2600,18 @@ class WebauthnCredential(db.Model):
"""
__tablename__ = "webauthn_credential"
credential_id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
aaguid = db.Column(UUID(as_uuid=True), default=uuid.uuid4, nullable=False)
public_key = db.Column(db.String, nullable=False)
id = db.Column(UUID(as_uuid=True), primary_key=True, nullable=False, default=uuid.uuid4)
user_id = db.Column(UUID(as_uuid=True), db.ForeignKey('users.id'), primary_key=True, nullable=False)
user_id = db.Column(UUID(as_uuid=True), db.ForeignKey('users.id'), nullable=False)
user = db.relationship(User, backref=db.backref("webauthn_credentials"))
registration_response = db.Column(JSONB(none_as_null=True), nullable=False, default={})
name = db.Column(db.String, nullable=False)
# base64 encoded CBOR. used for logging in. https://w3c.github.io/webauthn/#sctn-attested-credential-data
credential_data = db.Column(db.String, nullable=False)
# base64 encoded CBOR. used for auditing. https://www.w3.org/TR/webauthn-2/#authenticatorattestationresponse
registration_response = db.Column(db.String, nullable=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
updated_at = db.Column(db.DateTime, nullable=True, default=datetime.datetime.utcnow)
updated_at = db.Column(db.DateTime, nullable=True, onupdate=datetime.datetime.utcnow)

View File

@@ -14,24 +14,22 @@ down_revision = '0354_government_channel'
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
'webauthn_credential',
sa.Column('credential_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('aaguid', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('public_key', sa.String(), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('registration_response', postgresql.JSONB(none_as_null=True, astext_type=sa.Text()), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('credential_data', sa.String(), nullable=False),
sa.Column('registration_response', sa.String(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('credential_id', 'user_id')
)
# ### end Alembic commands ###
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('webauthn_credential')
# ### end Alembic commands ###