diff --git a/dispatcher/backend/docs/openapi_v1.yaml b/dispatcher/backend/docs/openapi_v1.yaml index f909a6a70..a8f8d9168 100644 --- a/dispatcher/backend/docs/openapi_v1.yaml +++ b/dispatcher/backend/docs/openapi_v1.yaml @@ -156,40 +156,6 @@ paths: $ref: '#/components/schemas/InputError' 401: description: Unauthorized - /auth/validate/ssh_key: - post: - tags: - - auth - summary: verify public key - operationId: validateKey - description: Checks that provided RSA public key is valid for User - requestBody: - content: - application/json: - schema: - type: object - required: - - username - - key - properties: - username: - $ref: '#/components/schemas/Username' - key: - type: string - format: base64 encoded RSA public key text - minLength: 1 - example: QUFBQUIzTnphQzF5YzJFQUFBQURBUUFCQUFBQkFRRERJUlNhbStHY0tBQW5tMGpGL1ZCMTJydFhDenBGRTFnc1Q5Q25GdzVkWWJQb2NudWdkbDY0UVpxNjVSdGN5T1BJVEJ0Yk1SOUw2ZEowejI2b21mZFhYd2VFcE5JR0N0SmRtNldzWTNrc0JyNHAvREhFRUVzSDkraGR3RVovQzd3YXlpbDZ3dUlwY3BMNXJLZ2xIRnlZVVJsNDQ5Nis0c0RjMG1YbllGdmVSMkdHRmNsdmwvcTdEejNla1RaNXV4THBhRFl4Y3NrZm5LVm1PQW82b04yYzRhbmtkZ2ozRkxmemRQeHFlakovUmRXVFF4dEtGQmt5VEZ0Wmt2SW9Ub2NXRENISWw0K1k1RExOYzlFTm1TZnlDbFdsYVRxaVlBZm4rY3QvZXNrZHFxK0dHY0pkVnAwREFSWUdMb3NNV3JQbm01WWdRL3EwOHEzcmNIZ1NzOG1I - responses: - 204: - description: Public key is valid for User - 400: - description: Bad Request (invalid input) - content: - application/json: - schema: - $ref: '#/components/schemas/InputError' - 401: - description: Unauthorized /schedules/: get: @@ -1406,7 +1372,6 @@ paths: - added - fingerprint - key - - last_used - name - pkcs8_key - type @@ -1421,10 +1386,6 @@ paths: key: type: string example: AAAAB3NzaC1yc2EAAAADAQABAAABAQDDIRSam+GcKAAnm0jF\/VB12rtXCzpFE1gsT9CnFw5dYbP - last_used: - type: string - format: date-time - example: "2019-08-12T08:22:10.519000Z" name: type: string example: my-key diff --git a/dispatcher/backend/src/common/schemas/orms.py b/dispatcher/backend/src/common/schemas/orms.py index d24ae79d2..a2d07e946 100644 --- a/dispatcher/backend/src/common/schemas/orms.py +++ b/dispatcher/backend/src/common/schemas/orms.py @@ -41,7 +41,6 @@ class Meta: added = auto_field() fingerprint = auto_field() key = auto_field() - last_used = auto_field() name = auto_field() pkcs8_key = auto_field() type = auto_field() diff --git a/dispatcher/backend/src/db/models.py b/dispatcher/backend/src/db/models.py index 1c77f30a9..394d4c6f7 100644 --- a/dispatcher/backend/src/db/models.py +++ b/dispatcher/backend/src/db/models.py @@ -133,7 +133,6 @@ class Sshkey(Base): type: Mapped[str] key: Mapped[str] added: Mapped[datetime] - last_used: Mapped[Optional[datetime]] pkcs8_key: Mapped[str] user_id: Mapped[UUID] = mapped_column(ForeignKey("user.id"), init=False) diff --git a/dispatcher/backend/src/migrations/versions/ceae21f592b7_remove_ssh_key_last_used.py b/dispatcher/backend/src/migrations/versions/ceae21f592b7_remove_ssh_key_last_used.py new file mode 100644 index 000000000..c6324e5ad --- /dev/null +++ b/dispatcher/backend/src/migrations/versions/ceae21f592b7_remove_ssh_key_last_used.py @@ -0,0 +1,33 @@ +"""remove_ssh_key_last_used + +Revision ID: ceae21f592b7 +Revises: 43f385b318d4 +Create Date: 2023-09-29 10:59:39.739351 + +""" +import sqlalchemy as sa +from alembic import op +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = "ceae21f592b7" +down_revision = "43f385b318d4" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("sshkey", "last_used") + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "sshkey", + sa.Column( + "last_used", postgresql.TIMESTAMP(), autoincrement=False, nullable=True + ), + ) + # ### end Alembic commands ### diff --git a/dispatcher/backend/src/routes/auth/__init__.py b/dispatcher/backend/src/routes/auth/__init__.py index 77abc7d5a..888d0a826 100644 --- a/dispatcher/backend/src/routes/auth/__init__.py +++ b/dispatcher/backend/src/routes/auth/__init__.py @@ -10,7 +10,7 @@ from common import getnow from db import dbsession from routes import API_PATH, authenticate -from routes.auth import ssh, validate +from routes.auth import ssh from routes.auth.oauth2 import OAuth2 from routes.errors import BadRequest, Unauthorized from utils.check import raise_if, raise_if_none @@ -125,6 +125,3 @@ def __init__(self): self.add_url_rule("/test", "test_auth", test, methods=["GET"]) self.add_url_rule("/token", "auth_with_token", refresh_token, methods=["POST"]) self.add_url_rule("/oauth2", "oauth2", OAuth2(), methods=["POST"]) - self.add_url_rule( - "/validate/ssh_key", "validate_ssh_key", validate.ssh_key, methods=["POST"] - ) diff --git a/dispatcher/backend/src/routes/auth/validate.py b/dispatcher/backend/src/routes/auth/validate.py deleted file mode 100644 index a6f9b74dd..000000000 --- a/dispatcher/backend/src/routes/auth/validate.py +++ /dev/null @@ -1,53 +0,0 @@ -import base64 -import binascii -from http import HTTPStatus - -import paramiko -import sqlalchemy as sa -import sqlalchemy.orm as so -from flask import Response, request -from marshmallow import Schema, ValidationError, validate - -import db.models as dbm -import errors.http as http_errors -from common import getnow -from common.schemas import String -from routes import errors -from utils.check import raise_if_none - - -def ssh_key(session: so.Session): - """ - Validate ssh public keys exists and matches with username - """ - - # validate request json - class KeySchema(Schema): - username = String(required=True, validate=validate.Length(min=1)) - key = String(required=True, validate=validate.Length(min=1)) - - try: - request_json = KeySchema().load(request.get_json()) - except ValidationError as e: - raise http_errors.InvalidRequestJSON(e.messages) - - # compute fingerprint - try: - key = request_json["key"] - rsa_key = paramiko.RSAKey(data=base64.b64decode(key)) - fingerprint = binascii.hexlify(rsa_key.get_fingerprint()).decode() - except (binascii.Error, paramiko.SSHException): - raise errors.BadRequest("Invalid RSA key") - - # database - username = request_json["username"] - orm_ssh_key = session.execute( - sa.select(dbm.Sshkey) - .join(dbm.User) - .where(dbm.User.username == username) - .where(dbm.Sshkey.fingerprint == fingerprint) - ).scalar_one_or_none() - raise_if_none(orm_ssh_key, errors.Unauthorized) - dbm.User.check(orm_ssh_key.user, errors.Unauthorized) - orm_ssh_key.last_used = getnow() - return Response(status=HTTPStatus.NO_CONTENT) diff --git a/dispatcher/backend/src/routes/users/keys.py b/dispatcher/backend/src/routes/users/keys.py index 0125e45ec..0cdd5abcf 100644 --- a/dispatcher/backend/src/routes/users/keys.py +++ b/dispatcher/backend/src/routes/users/keys.py @@ -100,7 +100,6 @@ def post(self, username: str, token: AccessToken.Payload, session: so.Session): key=key, type="RSA", added=sa.func.current_timestamp(), - last_used=None, pkcs8_key=pkcs8_key, ) ssh_key.user_id = current_user.id diff --git a/dispatcher/backend/src/tests/integration/routes/conftest.py b/dispatcher/backend/src/tests/integration/routes/conftest.py index 99faff3ea..33e54aa71 100644 --- a/dispatcher/backend/src/tests/integration/routes/conftest.py +++ b/dispatcher/backend/src/tests/integration/routes/conftest.py @@ -173,7 +173,6 @@ def _make_key() -> dict: ), "type": "RSA", "added": datetime.datetime(2019, 1, 1), - "last_used": datetime.datetime(2019, 1, 1), "pkcs8_key": "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuBGJjT33bHGmHDE13tDc\n" "UqUvuam1Tvlg2jC7fyS2w5qKyc8wWBSLcbK+Yb8SnJEN44FHXKCKs6cH44PPDYcX\n" @@ -212,7 +211,6 @@ def _make_user( key=key["key"], type=key["type"], added=key["added"], - last_used=key["last_used"], pkcs8_key=key["pkcs8_key"], ) ) @@ -234,7 +232,6 @@ def _make_user( "key": key.key, "type": key.type, "added": key.added, - "last_used": key.last_used, "pkcs8_key": key.pkcs8_key, } for key in user.ssh_keys diff --git a/dispatcher/frontend-ui/src/views/UserView.vue b/dispatcher/frontend-ui/src/views/UserView.vue index 7f497f909..208a79feb 100644 --- a/dispatcher/frontend-ui/src/views/UserView.vue +++ b/dispatcher/frontend-ui/src/views/UserView.vue @@ -59,7 +59,6 @@ SSH Key - Last Used Fingerprint Delete @@ -67,7 +66,6 @@ {{ ssh_key.name }} - {{ ssh_key.last_used | from_now }} {{ ssh_key.fingerprint }} Delete