diff --git a/app/models.py b/app/models.py index 7abeaf848..9c471b5f2 100644 --- a/app/models.py +++ b/app/models.py @@ -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) diff --git a/migrations/versions/0355_add_webauthn_table.py b/migrations/versions/0355_add_webauthn_table.py index 6e25ede16..ed0e23967 100644 --- a/migrations/versions/0355_add_webauthn_table.py +++ b/migrations/versions/0355_add_webauthn_table.py @@ -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 ###