From 15d62ff097c76573f811bf5ccc3cd6c90da36206 Mon Sep 17 00:00:00 2001 From: Ionesio Junior Date: Sat, 24 Feb 2024 10:23:20 -0300 Subject: [PATCH] ADD sender_email parameter and add helm configs --- packages/grid/backend/grid/core/config.py | 1 + packages/grid/backend/grid/core/node.py | 1 + packages/grid/default.env | 5 ++- .../syft/templates/backend-statefulset.yaml | 8 +++-- packages/grid/helm/syft/values.yaml | 3 ++ packages/hagrid/hagrid/cli.py | 10 ++++++ packages/syft/src/syft/node/node.py | 7 ++-- .../src/syft/service/notifier/notifier.py | 32 ++++++++----------- .../syft/service/notifier/notifier_service.py | 17 ++++++++-- .../syft/service/settings/settings_service.py | 2 ++ 10 files changed, 59 insertions(+), 27 deletions(-) diff --git a/packages/grid/backend/grid/core/config.py b/packages/grid/backend/grid/core/config.py index 830e67503f5..98fd8fbb64d 100644 --- a/packages/grid/backend/grid/core/config.py +++ b/packages/grid/backend/grid/core/config.py @@ -143,6 +143,7 @@ def get_emails_enabled(cls, v: bool, values: Dict[str, Any]) -> bool: CONSUMER_SERVICE_NAME: Optional[str] = os.getenv("CONSUMER_SERVICE_NAME") INMEMORY_WORKERS: bool = str_to_bool(os.getenv("INMEMORY_WORKERS", True)) SMTP_USERNAME: str = os.getenv("SMTP_USERNAME", "") + EMAIL_SENDER: str = os.getenv("EMAIL_SENDER", "") SMTP_PASSWORD: str = os.getenv("SMTP_PASSWORD", "") TEST_MODE: bool = ( diff --git a/packages/grid/backend/grid/core/node.py b/packages/grid/backend/grid/core/node.py index e81583c347e..bb5d3a865e1 100644 --- a/packages/grid/backend/grid/core/node.py +++ b/packages/grid/backend/grid/core/node.py @@ -96,4 +96,5 @@ def seaweedfs_config() -> SeaweedFSConfig: in_memory_workers=settings.INMEMORY_WORKERS, smtp_username=settings.SMTP_USERNAME, smtp_password=settings.SMTP_PASSWORD, + email_sender=settings.EMAIL_SENDER, ) diff --git a/packages/grid/default.env b/packages/grid/default.env index edfbed1b18c..1e446383156 100644 --- a/packages/grid/default.env +++ b/packages/grid/default.env @@ -43,9 +43,9 @@ DEFAULT_ROOT_PASSWORD=changethis SMTP_TLS=True SMTP_PORT=587 SMTP_HOST= -SMTP_USER= +SMTP_USERNAME= SMTP_PASSWORD= -EMAILS_FROM_EMAIL=info@openmined.org +EMAIL_SENDER= SERVER_HOST="https://${DOMAIN}" NETWORK_CHECK_INTERVAL=60 DOMAIN_CHECK_INTERVAL=60 @@ -56,7 +56,6 @@ QUEUE_PORT=5556 CREATE_PRODUCER=False N_CONSUMERS=1 INMEMORY_WORKERS=True -EMAIL_TOKEN="" # New Service Flag USE_NEW_SERVICE=False diff --git a/packages/grid/helm/syft/templates/backend-statefulset.yaml b/packages/grid/helm/syft/templates/backend-statefulset.yaml index a66de0d142d..a51fc20c149 100644 --- a/packages/grid/helm/syft/templates/backend-statefulset.yaml +++ b/packages/grid/helm/syft/templates/backend-statefulset.yaml @@ -114,10 +114,14 @@ spec: value: "true" - name: N_CONSUMERS value: "0" + - name: SMTP_USERNAME + value: {{ .Values.node.settings.smtpUserName }} + - name: SMTP_PASSWORD + value: {{ .Values.node.settings.smtpPassword }} + - name: EMAIL_SENDER + value: {{ .Values.node.settings.smtpSender }} - name: INMEMORY_WORKERS value: "{{ .Values.node.settings.inMemoryWorkers }}" - - name: EMAIL_TOKEN - value: {{ .Values.node.settings.emailToken }} - name: LOG_LEVEL value: {{ .Values.node.settings.logLevel }} - name: DEFAULT_WORKER_POOL_IMAGE diff --git a/packages/grid/helm/syft/values.yaml b/packages/grid/helm/syft/values.yaml index 84f03c797df..bd6ca40b9f2 100644 --- a/packages/grid/helm/syft/values.yaml +++ b/packages/grid/helm/syft/values.yaml @@ -40,6 +40,9 @@ node: versionHash: "abc" nodeSideType: "high" defaultRootEmail: "info@openmined.org" + smtpUserName: "apikey" + smtpPassword: "password" + smtpSender: "info@openmined.org" logLevel: "info" inMemoryWorkers: false defaultWorkerPoolCount: 1 diff --git a/packages/hagrid/hagrid/cli.py b/packages/hagrid/hagrid/cli.py index 6dec82af707..4e49e4e85f9 100644 --- a/packages/hagrid/hagrid/cli.py +++ b/packages/hagrid/hagrid/cli.py @@ -336,6 +336,13 @@ def clean(location: str) -> None: type=str, help="Password used to auth in email server and enable notification via emails", ) +@click.option( + "--smtp-sender", + default=None, + required=False, + type=str, + help="Sender email used to deliver PyGrid email notifications.", +) @click.option( "--build-src", default=DEFAULT_BRANCH, @@ -1325,6 +1332,7 @@ def create_launch_cmd( parsed_kwargs["smtp_username"] = kwargs["smtp_username"] parsed_kwargs["smtp_password"] = kwargs["smtp_password"] + parsed_kwargs["smtp_sender"] = kwargs["smtp_sender"] parsed_kwargs["enable_warnings"] = not kwargs["no_warnings"] @@ -2174,6 +2182,7 @@ def create_launch_docker_cmd( single_container_mode = kwargs["deployment_type"] == "single_container" in_mem_workers = kwargs.get("in_mem_workers") smtp_username = kwargs.get("smtp_username") + smtp_sender = kwargs.get("smtp_sender") smtp_password = kwargs.get("smtp_password") enable_oblv = bool(kwargs["oblv"]) @@ -2241,6 +2250,7 @@ def create_launch_docker_cmd( "INMEMORY_WORKERS": in_mem_workers, "SMTP_USERNAME": smtp_username, "SMTP_PASSWORD": smtp_password, + "EMAIL_SENDER": smtp_sender, } if "trace" in kwargs and kwargs["trace"] is True: diff --git a/packages/syft/src/syft/node/node.py b/packages/syft/src/syft/node/node.py index 75fb9540829..fb563a61639 100644 --- a/packages/syft/src/syft/node/node.py +++ b/packages/syft/src/syft/node/node.py @@ -312,7 +312,7 @@ def __init__( in_memory_workers: bool = True, smtp_username: Optional[str] = None, smtp_password: Optional[str] = None, - email_token: Optional[str] = None, + email_sender: Optional[str] = None, ): # 🟡 TODO 22: change our ENV variable format and default init args to make this # less horrible or add some convenience functions @@ -400,7 +400,10 @@ def __init__( ) NotifierService.init_notifier( - node=self, email_password=smtp_password, email_username=smtp_username + node=self, + email_password=smtp_password, + email_username=smtp_username, + email_sender=email_sender, ) self.client_cache = {} diff --git a/packages/syft/src/syft/service/notifier/notifier.py b/packages/syft/src/syft/service/notifier/notifier.py index d334ac43dd8..a4ffd7a1d29 100644 --- a/packages/syft/src/syft/service/notifier/notifier.py +++ b/packages/syft/src/syft/service/notifier/notifier.py @@ -24,7 +24,7 @@ from .notifier_enums import NOTIFIERS from .smtp_client import SMTPClient -DEFAULT_EMAIL_SERVER = "smtp.postmarkapp.com" +DEFAULT_EMAIL_SERVER = "smtp.sendgrid.net" class BaseNotifier: @@ -38,27 +38,22 @@ def send( class EmailNotifier(BaseNotifier): smtp_client = SMTPClient - username: str - password: str - server: str - port: int + sender = "" def __init__( self, username: str, password: str, + sender: str, server: str = DEFAULT_EMAIL_SERVER, port: int = 587, ) -> None: - self.username = username - self.password = password - self.server = server - self.port = port + self.sender = sender self.smtp_client = SMTPClient( - server=self.server, - port=self.port, - username=self.username, - password=self.password, + server=server, + port=port, + username=username, + password=password, ) @classmethod @@ -81,9 +76,7 @@ def send( ) -> Result[Ok, Err]: try: user_service = context.node.get_service("userservice") - sender_email = user_service.get_by_verify_key( - notification.from_user_verify_key - ).email + receiver_email = user_service.get_by_verify_key( notification.to_user_verify_key ).email @@ -97,7 +90,7 @@ def send( receiver_email = [receiver_email] self.smtp_client.send( - sender=sender_email, receiver=receiver_email, subject=subject, body=body + sender=self.sender, receiver=receiver_email, subject=subject, body=body ) return Ok("Email sent successfully!") except Exception: @@ -131,6 +124,7 @@ class NotifierSettings(SyftObject): NOTIFIERS.APP: False, } + email_sender: Optional[str] = "" email_server: Optional[str] = DEFAULT_EMAIL_SERVER email_port: Optional[int] = 587 email_username: Optional[str] = "" @@ -201,7 +195,9 @@ def select_notifiers(self, notification: Notification) -> List[BaseNotifier]: if notifier_type == NOTIFIERS.EMAIL: notifier_objs.append( self.notifiers[notifier_type]( - username=self.email_username, password=self.email_password + username=self.email_username, + password=self.email_password, + sender=self.email_sender, ) ) # If notifier is not email, we just create the notifier object diff --git a/packages/syft/src/syft/service/notifier/notifier_service.py b/packages/syft/src/syft/service/notifier/notifier_service.py index 1e5b3f3d49d..f430674b08d 100644 --- a/packages/syft/src/syft/service/notifier/notifier_service.py +++ b/packages/syft/src/syft/service/notifier/notifier_service.py @@ -58,13 +58,14 @@ def turn_on( context: AuthedServiceContext, email_username: Optional[str] = None, email_password: Optional[str] = None, + email_sender: Optional[str] = None, ) -> Union[SyftSuccess, SyftError]: """Turn on email notifications. Args: email_username (Optional[str]): Email server username. Defaults to None. email_password (Optional[str]): Email email server password. Defaults to None. - + sender_email (Optional[str]): Email sender email. Defaults to None. Returns: Union[SyftSuccess, SyftError]: A union type representing the success or error response. @@ -108,6 +109,11 @@ def turn_on( username=email_username, password=email_password ) + if not email_sender and not notifier.email_sender: + return SyftError( + message="You must provide a sender email address to enable notifications." + ) + if validation_result.is_err(): return SyftError( message="Invalid SMTP credentials. Please check your username and password." @@ -115,6 +121,10 @@ def turn_on( notifier.email_password = email_password notifier.email_username = email_username + + if email_sender: + notifier.email_sender = email_sender + notifier.active = True print( "[LOG] Email credentials are valid. Updating the notifier settings in the db." @@ -223,6 +233,7 @@ def init_notifier( node: AbstractNode, email_username: Optional[str] = None, email_password: Optional[str] = None, + email_sender: Optional[str] = None, ) -> Result[Ok, Err]: """Initialize Notifier settings for a Node. If settings already exist, it will use the existing one. @@ -259,11 +270,13 @@ def init_notifier( username=email_username, password=email_password ) - if validation_result.is_err(): + sender_not_set = not email_sender and not notifier.email_sender + if validation_result.is_err() or sender_not_set: notifier.active = False else: notifier.email_password = email_password notifier.email_username = email_username + notifier.email_sender = email_sender notifier.active = True notifier_stash.set(node.signing_key.verify_key, notifier) diff --git a/packages/syft/src/syft/service/settings/settings_service.py b/packages/syft/src/syft/service/settings/settings_service.py index 72790e16d04..c23aad025ab 100644 --- a/packages/syft/src/syft/service/settings/settings_service.py +++ b/packages/syft/src/syft/service/settings/settings_service.py @@ -92,12 +92,14 @@ def enable_notifications( context: AuthedServiceContext, email_username: Optional[str] = None, email_password: Optional[str] = None, + email_sender: Optional[str] = None, ) -> Union[SyftSuccess, SyftError]: notifier_service = context.node.get_service("notifierservice") return notifier_service.turn_on( context=context, email_username=email_username, email_password=email_password, + email_sender=email_sender, ) @service_method(