Skip to content

Commit

Permalink
create internal auth mntner without migration
Browse files Browse the repository at this point in the history
q committed Oct 28, 2024
1 parent d56d503 commit 42b8cc9
Showing 3 changed files with 68 additions and 11 deletions.
46 changes: 45 additions & 1 deletion irrd/updates/handler.py
Original file line number Diff line number Diff line change
@@ -9,9 +9,10 @@
from irrd.conf import get_setting
from irrd.rpsl.rpsl_objects import RPSLMntner
from irrd.storage.database_handler import DatabaseHandler
from irrd.storage.models import AuthoritativeChangeOrigin, AuthUser
from irrd.storage.models import AuthoritativeChangeOrigin, AuthUser, AuthMntner, AuthPermission, RPSLDatabaseObject
from irrd.storage.queries import RPSLDatabaseQuery
from irrd.utils import email
from ..storage.orm_provider import ORMSessionProvider

from ..utils.validators import RPSLChangeSubmission, RPSLSuspensionSubmission
from .parser import ChangeRequest, SuspensionRequest, parse_change_requests
@@ -40,6 +41,7 @@ def load_text_blob(
self.database_handler = DatabaseHandler()
self.request_meta = request_meta if request_meta else {}
self._pgp_key_id = self._resolve_pgp_key_id(pgp_fingerprint) if pgp_fingerprint else None
self.new_internal_auths = []

reference_validator = ReferenceValidator(self.database_handler)
auth_validator = AuthValidator(
@@ -56,6 +58,7 @@ def load_text_blob(
self._handle_change_requests(change_requests, reference_validator, auth_validator)
self.database_handler.commit()
self.database_handler.close()
self._handle_new_internal_auths(auth_validator)
return self

def load_change_submission(
@@ -68,6 +71,7 @@ def load_change_submission(
):
self.database_handler = DatabaseHandler()
self.request_meta = request_meta if request_meta else {}
self.new_internal_auths = []

reference_validator = ReferenceValidator(self.database_handler)
auth_validator = AuthValidator(self.database_handler, origin, remote_ip=remote_ip)
@@ -106,13 +110,15 @@ def load_change_submission(
self._handle_change_requests(change_requests, reference_validator, auth_validator)
self.database_handler.commit()
self.database_handler.close()
self._handle_new_internal_auths(auth_validator)
return self

def load_suspension_submission(
self, data: RPSLSuspensionSubmission, request_meta: Optional[Dict[str, Optional[str]]] = None
):
self.database_handler = DatabaseHandler()
self.request_meta = request_meta if request_meta else {}
self.new_internal_auths = []

reference_validator = ReferenceValidator(self.database_handler)
auth_validator = AuthValidator(self.database_handler)
@@ -136,6 +142,7 @@ def load_suspension_submission(
self._handle_change_requests(change_requests, reference_validator, auth_validator)
self.database_handler.commit()
self.database_handler.close()
self._handle_new_internal_auths(auth_validator)
return self

def _handle_change_requests(
@@ -190,8 +197,45 @@ def _handle_change_requests(
if result.is_valid():
result.save()

# Insert internal authentication for newly created mntners
if result.request_type == UpdateRequestType.CREATE and isinstance(result.rpsl_obj_new, RPSLMntner) \
and result.rpsl_obj_new.has_internal_auth():
self.new_internal_auths.append(result.rpsl_obj_new)

self.results = change_requests

def _handle_new_internal_auths(self, auth_validator: AuthValidator):
user = auth_validator.user()
if not user:
return

session_provider = ORMSessionProvider()

for rpsl_obj in self.new_internal_auths:
query = session_provider.session.query(RPSLDatabaseObject)
query = query.filter(
RPSLDatabaseObject.rpsl_pk == rpsl_obj.pk(),
RPSLDatabaseObject.source == rpsl_obj.source(),
RPSLDatabaseObject.object_class == "mntner",
)
mntner_obj = session_provider.run_sync(query.one)
new_auth_mntner = AuthMntner(
rpsl_mntner_pk=rpsl_obj.pk(),
rpsl_mntner_obj_id=str(mntner_obj.pk),
rpsl_mntner_source=rpsl_obj.source(),
)
session_provider.session.add(new_auth_mntner)
session_provider.session.commit()
new_permission = AuthPermission(
user_id=str(user.pk),
mntner_id=str(new_auth_mntner.pk),
user_management=True,
)
session_provider.session.add(new_permission)
session_provider.session.commit()

session_provider.commit_close()

def _resolve_pgp_key_id(self, pgp_fingerprint: str) -> Optional[str]:
"""
Find a PGP key ID for a given fingerprint.
2 changes: 1 addition & 1 deletion irrd/updates/parser.py
Original file line number Diff line number Diff line change
@@ -325,7 +325,7 @@ def validate(self) -> bool:
self.status = UpdateRequestStatus.ERROR_PARSING
return False
if self.rpsl_obj_new and self.request_type and self.request_type != UpdateRequestType.DELETE:
rules_result = self.rules_validator.validate(self.rpsl_obj_new, self.request_type)
rules_result = self.rules_validator.validate(self.rpsl_obj_new, self.request_type, self.auth_validator.user())
self.info_messages += rules_result.info_messages
self.error_messages += rules_result.error_messages
if not rules_result.is_valid():
31 changes: 22 additions & 9 deletions irrd/updates/validators.py
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
PROTECTED_NAME_OBJECT_CLASSES,
RPSLMntner,
RPSLSet,
rpsl_object_from_text,
rpsl_object_from_text, RPSLAutNum, RPSLAsBlock, RPSLInetnum, RPSLInet6Num,
)
from irrd.storage.database_handler import DatabaseHandler
from irrd.storage.models import (
@@ -317,6 +317,9 @@ def __init__(
self.keycert_obj_pk = keycert_obj_pk
self._internal_authenticated_user = internal_authenticated_user

def user(self) -> Optional[AuthUser]:
return self._internal_authenticated_user

def pre_approve(self, presumed_valid_new_mntners: List[RPSLMntner]) -> None:
"""
Pre-approve certain maintainers that are part of this batch of updates.
@@ -354,7 +357,7 @@ def process_auth(
logger.info("Found valid override password.")
return result

mntners_new = rpsl_obj_new.parsed_data["mnt-by"]
mntners_new = rpsl_obj_new.parsed_data.get("mnt-by", [])
logger.debug(f"Checking auth for new object {rpsl_obj_new}, mntners in new object: {mntners_new}")
new_mntners_result = self._check_mntners(rpsl_obj_new, mntners_new, source)
if not new_mntners_result.valid:
@@ -393,9 +396,6 @@ def process_auth(
result.error_messages.add("New inet(6)num objects must be added by an administrator.")

if isinstance(rpsl_obj_new, RPSLMntner):
if not rpsl_obj_current:
result.error_messages.add("New mntner objects must be added by an administrator.")
return result
# Dummy auth values are only permitted in existing objects
if rpsl_obj_new.has_dummy_auth_value():
if len(self.passwords) == 1:
@@ -420,7 +420,7 @@ def process_auth(
self._mntner_matches_internal_auth(rpsl_obj_new, rpsl_obj_new.pk(), source),
# API keys are not checked here, as they can never be used on RPSLMntner
]
):
) and not rpsl_obj_new.pk() in self._pre_approved:
result.error_messages.add("Authorisation failed for the auth methods on this mntner object.")

if isinstance(rpsl_obj_new, RPSLAutNum) or isinstance(rpsl_obj_new, RPSLAsBlock):
@@ -718,7 +718,7 @@ class RulesValidator:
def __init__(self, database_handler: DatabaseHandler) -> None:
self.database_handler = database_handler

def validate(self, rpsl_obj: RPSLObject, request_type: UpdateRequestType) -> ValidatorResult:
def validate(self, rpsl_obj: RPSLObject, request_type: UpdateRequestType, user: Optional[AuthUser]) -> ValidatorResult:
result = ValidatorResult()

if (
@@ -738,9 +738,22 @@ def validate(self, rpsl_obj: RPSLObject, request_type: UpdateRequestType) -> Val
f"This maintainer is migrated and must include the {RPSL_MNTNER_AUTH_INTERNAL} method."
)
elif not is_migrated and has_internal_auth:
if not user:
result.error_messages.add(
"This maintainer is not migrated, and therefore can not use the "
f"{RPSL_MNTNER_AUTH_INTERNAL} method. "
f"Login to create a new maintainer with {RPSL_MNTNER_AUTH_INTERNAL}"
)
elif request_type != UpdateRequestType.CREATE:
result.error_messages.add(
"This maintainer is not migrated, and therefore can not use the "
f"{RPSL_MNTNER_AUTH_INTERNAL} method."
)

if rpsl_obj.rpsl_object_class in ("person", "role"):
if not rpsl_obj.pk().endswith(f"-{rpsl_obj.source()}"):
result.error_messages.add(
"This maintainer is not migrated, and therefore can not use the"
f" {RPSL_MNTNER_AUTH_INTERNAL} method."
f"nic-hdls in {rpsl_obj.source()} must end with -{rpsl_obj.source()}"
)

return result

0 comments on commit 42b8cc9

Please sign in to comment.