diff --git a/atst/domain/csp/cloud/__init__.py b/atst/domain/csp/cloud/__init__.py index 99128d9c..c3cc5dc0 100644 --- a/atst/domain/csp/cloud/__init__.py +++ b/atst/domain/csp/cloud/__init__.py @@ -1,3 +1,7 @@ from .azure_cloud_provider import AzureCloudProvider from .cloud_provider_interface import CloudProviderInterface from .mock_cloud_provider import MockCloudProvider +from .utils import ( + generate_mail_nickname, + generate_user_principal_name, +) diff --git a/atst/domain/csp/cloud/models.py b/atst/domain/csp/cloud/models.py index 27f2c9c7..4a80084b 100644 --- a/atst/domain/csp/cloud/models.py +++ b/atst/domain/csp/cloud/models.py @@ -4,9 +4,12 @@ from typing import Dict, List, Optional from uuid import uuid4 import re -from flask import current_app as app from pydantic import BaseModel, validator, root_validator +from .utils import ( + generate_mail_nickname, + generate_user_principal_name, +) from atst.utils import snake_to_camel @@ -527,11 +530,11 @@ class UserMixin(BaseModel): @property def user_principal_name(self): - return f"{self.mail_nickname}@{self.tenant_host_name}.{app.config.get('OFFICE_365_DOMAIN')}" + return generate_user_principal_name(self.display_name, self.tenant_host_name) @property def mail_nickname(self): - return self.display_name.replace(" ", ".").lower() + return generate_mail_nickname(self.display_name) @validator("password", pre=True, always=True) def supply_password_default(cls, password): diff --git a/atst/domain/csp/cloud/utils.py b/atst/domain/csp/cloud/utils.py new file mode 100644 index 00000000..883e69d2 --- /dev/null +++ b/atst/domain/csp/cloud/utils.py @@ -0,0 +1,10 @@ +from flask import current_app as app + + +def generate_user_principal_name(name, domain_name): + mail_name = generate_mail_nickname(name) + return f"{mail_name}@{domain_name}.{app.config.get('OFFICE_365_DOMAIN')}" + + +def generate_mail_nickname(name): + return name.replace(" ", ".").lower() diff --git a/atst/jobs.py b/atst/jobs.py index 1dbff894..dcfb4bf3 100644 --- a/atst/jobs.py +++ b/atst/jobs.py @@ -6,7 +6,7 @@ from azure.core.exceptions import AzureError from atst.database import db from atst.domain.application_roles import ApplicationRoles from atst.domain.applications import Applications -from atst.domain.csp.cloud import CloudProviderInterface +from atst.domain.csp.cloud import CloudProviderInterface, generate_user_principal_name from atst.domain.csp.cloud.exceptions import GeneralCSPException from atst.domain.csp.cloud.models import ( ApplicationCSPPayload, @@ -177,9 +177,10 @@ def do_create_environment_role(csp: CloudProviderInterface, environment_role_id= env_role.cloud_id = result.id db.session.add(env_role) db.session.commit() + user = env_role.application_role.user - mail_name = user.full_name.replace(" ", ".").lower() - username = f"{mail_name}@{csp_details.get('tennant_id')}.{app.config.get('OFFICE_365_DOMAIN')}" + domain_name = csp_details.get("domain_name") + username = generate_user_principal_name(user.full_name, domain_name,) send_mail( recipients=[user.email], subject=translate("email.azure_account_update.subject"), @@ -189,7 +190,7 @@ def do_create_environment_role(csp: CloudProviderInterface, environment_role_id= ), ) app.logger.info( - f"Notification email sent for enivornment role creation. User id: {user.id}" + f"Notification email sent for environment role creation. User id: {user.id}" ) @@ -208,7 +209,7 @@ def send_PPOC_email(portfolio_dict): ppoc_email = portfolio_dict.get("password_recovery_email_address") user_id = portfolio_dict.get("user_id") domain_name = portfolio_dict.get("domain_name") - + username = generate_user_principal_name(user_id, domain_name) send_mail( recipients=[ppoc_email], subject=translate("email.portfolio_ready.subject"), @@ -216,7 +217,7 @@ def send_PPOC_email(portfolio_dict): "email.portfolio_ready.body", { "password_reset_address": app.config.get("AZURE_LOGIN_URL"), - "username": f"{user_id}@{domain_name}.{app.config.get('OFFICE_365_DOMAIN')}", + "username": username, }, ), ) diff --git a/atst/models/portfolio.py b/atst/models/portfolio.py index bd430ed3..0243b215 100644 --- a/atst/models/portfolio.py +++ b/atst/models/portfolio.py @@ -12,10 +12,10 @@ from sqlalchemy_json import NestedMutableJson from atst.database import db import atst.models.mixins as mixins import atst.models.types as types +from atst.domain.csp.cloud import generate_mail_nickname from atst.domain.permission_sets import PermissionSets from atst.models.base import Base -from atst.models.portfolio_role import PortfolioRole -from atst.models.portfolio_role import Status as PortfolioRoleStatus +from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus from atst.utils import first_or_none @@ -188,7 +188,7 @@ class Portfolio( @property def domain_name(self): """ - CSP domain name associated with portfolio. + CSP domain name associated with portfolio. If a domain name is not set, generate one. """ domain_name = re.sub("[^0-9a-zA-Z]+", "", self.name).lower() + "".join( @@ -205,7 +205,9 @@ class Portfolio( def to_dictionary(self): return { - "user_id": f"{self.owner.first_name[0]}{self.owner.last_name}".lower(), + "user_id": generate_mail_nickname( + f"{self.owner.first_name[0]}{self.owner.last_name}" + ), "password": "", "domain_name": self.domain_name, "first_name": self.owner.first_name,