← Back to list

Using Janssen Project to send email from a SCIM create user request

Sometimes when you bulk import a batch of users by calling the SCIM API, you may want to set a starter password and email it to the end…

Mostafejur Rahman · 2024-03-26 23:08 · 0 claps · 4.3 min read
#open-source #janssen #gluu-server #scim2 #identity-management
Open on Medium ↗
Wiki topics: BIZ · Business Strategy 🔓 · Open Source

Using Janssen Project to send email from a SCIM create user request

Sometimes when you bulk import a batch of users by calling the SCIM API, you may want to set a starter password and email it to the end user. It’s not great for security of course, because email is not encrypted. But if you need to do something like this, keep reading!

Linux Foundation Janssen Project distribution An open source digital identity platforms that scales, Janssen is a software distribution of standards-based. A component of the Janssen Project that implements a standards-compliant SCIM service.

SCIM is a specification designed to reduce the complexity of user management operations by providing a common user schema and the patterns for exchanging such schema using HTTP in a platform-neutral fashion. The aim of SCIM is achieving interoperability, security, and scalability in the context of identity management.

In this blog, we will delve into managing Jans Server to send emails triggered by a SCIM create user request. We’ll cover the setup of custom scripts, including the configuration settings required to enable them, and explore how to tailor these scripts to customize the email content. Additionally, we’ll demonstrate how to configure the SMTP server and incorporate SMTP settings within our custom script for seamless email delivery.

Prerequisite

Let’s harness the power of the Jans Interception script. We’ll modify the SCIM custom script. You can obtain a sample from here or utilize the Jans TUI go to Scripts > scim_event_handler

The necessary classes to import in our scripts are:

  • UserPersistenceHelper: Manages data persistence from the database.
  • ScimCustomePerson : Represents the user entity model.
  • ConfigurationService : Retrieves SMTP configuration settings.

We will follow some steps:

Step 1 : Modify thepostCreateUser method.


     def postCreateUser(self, user, configurationAttributes):
        print("POST CREATE USER: post create user")     
        inum = user.getInum()   
        uid = user.getUid()
        print("POST CREATE USER: INUM is : %s"%inum)

        userPersistenceHelper = CdiUtil.bean(UserPersistenceHelper)        
        scimCustomePerson = userPersistenceHelper.getPersonByInum(inum)

        otp = Otp()      
        password = str(otp.generateOtp(self.length))     
        print("New OTP is : %s"%password)  

        scimCustomePerson.setUserPassword(password)  
        userPersistenceHelper.updatePerson(scimCustomePerson)  

        mails = scimCustomePerson.getAttributeList("mail")        
        for mail in mails:
            print("POST CREATE USER: user mail : %s"%mail)        
            subject = "Welcome to Gluu Inc.!"
            body = "Hello <b> %s</b>,<br> \n\
            Welcome to Gluu Inc.! <br>\
            Please use this One Time Password (OTP) for your first-time login. After logging in, please create your own password.<h1>%s </h1> " %(uid, password)       
            sender = EmailSender()       
            sender.sendEmail(mail, subject, body)
            print("POST CREATE USER: OTP send successfully")
            break

        return True

[N.B] Users may have multiple email addresses, so customize the logic according to their needs.

Step 2 : Create thegenerateOtp() function

class Otp:
    #class that deals with string otp

    def generateOtp(self,lent):
        rand1="1234567890123456789123456789"
        rand2="9876543210123456789123456789"
        first = int(rand1[:int(lent)])
        first1 = int(rand2[:int(lent)])
        otp = random.randint(first, first1)
        return otp

Step 3: Create thesendEmail() function

class EmailSender():

    def getSmtpConfig(self):

        smtp_config = None
        smtpconfig = CdiUtil.bean(ConfigurationService).getConfiguration().getSmtpConfiguration()

        if smtpconfig is None:
            print "Sign Email - SMTP CONFIG DOESN'T EXIST - Please configure"

        else:
            encryptionService = CdiUtil.bean(EncryptionService)
            print("SMTP config: %s"%smtpconfig)
            smtp_config = {
                'host' : smtpconfig.getHost(),
                'port' : smtpconfig.getPort(),
                'user' : smtpconfig.getFromName(),
                'from' : smtpconfig.getFromEmailAddress(),
                'pwd_decrypted' : encryptionService.decrypt(smtpconfig.getSmtpAuthenticationAccountPassword()),
                'requires_authentication' : smtpconfig.isRequiresAuthentication(),
                'server_trust' : smtpconfig.isServerTrust()
            }

        return smtp_config

    def sendEmail(self,  useremail, subject, messageText):
        # server connection
        try:        
            smtpconfig = self.getSmtpConfig()

            properties = Properties()
            properties.setProperty("mail.smtp.host", smtpconfig['host'])
            properties.setProperty("mail.smtp.port", str(smtpconfig['port']))
            properties.setProperty("mail.smtp.starttls.enable", "true")
            session = Session.getDefaultInstance(properties)

            message = MimeMessage(session)
            message.setFrom(InternetAddress(smtpconfig['from']))
            message.addRecipient(Message.RecipientType.TO,InternetAddress(useremail))
            message.setSubject(subject)
            #message.setText(messageText)
            message.setContent(messageText, "text/html")

            transport = session.getTransport("smtp")
            transport.connect(properties.get("mail.smtp.host"),int(properties.get("mail.smtp.port")), smtpconfig['from'], smtpconfig['pwd_decrypted'])
            transport.sendMessage(message,message.getRecipients(Message.RecipientType.TO))

            transport.close()
        except Exception as e:
            print(e)   

So our script looks like this.

# Visit https://www.gluu.org/docs/gluu-server/user-management/scim-scripting/ to learn more
from io.jans.model.custom.script.type.scim import ScimType
from io.jans.util import StringHelper, ArrayHelper
from java.util import Arrays, ArrayList
from io.jans.service.cdi.util import CdiUtil
from io.jans.scim.model.scim import ScimCustomPerson
from io.jans.scim.service.scim2 import UserPersistenceHelper
from io.jans.scim.service import ConfigurationService
from io.jans.service import EncryptionService
from java.security import Security
from javax.mail.internet import MimeMessage, InternetAddress
from javax.mail import Session, Message, Transport
from java.util import Enumeration, Properties
import random
import java

class ScimEventHandler(ScimType):

    def __init__(self, currentTimeMillis):
        self.currentTimeMillis = currentTimeMillis

    def init(self, configurationAttributes):
        print "ScimEventHandler (init): Initialized successfully"
        self.length = configurationAttributes.get("otp_length").getValue2()
        return True   

    def destroy(self, configurationAttributes):
        print "ScimEventHandler (destroy): Destroyed successfully"
        return True   

    def getApiVersion(self):
        return 5

    def createUser(self, user, configurationAttributes):
        return True

    def updateUser(self, user, configurationAttributes):
        return True

    def deleteUser(self, user, configurationAttributes):
        return True

    def createGroup(self, group, configurationAttributes):
        return True

    def updateGroup(self, group, configurationAttributes):
        return True

    def deleteGroup(self, group, configurationAttributes):
        return True

    def postCreateUser(self, user, configurationAttributes):
        print("POST CREATE USER: post create user")     
        inum = user.getInum()   
        uid = user.getUid()
        print("POST CREATE USER: INUM is : %s"%inum)

        userPersistenceHelper = CdiUtil.bean(UserPersistenceHelper)        
        scimCustomePerson = userPersistenceHelper.getPersonByInum(inum)

        otp = Otp()      
        password = str(otp.generateOtp(self.length))     
        print("New OTP is : %s"%password)  

        scimCustomePerson.setUserPassword(password)  
        userPersistenceHelper.updatePerson(scimCustomePerson)  

        mails = scimCustomePerson.getAttributeList("mail")        
        for mail in mails:
            print("POST CREATE USER: user mail : %s"%mail)        
            subject = "Welcome to Gluu Inc.!"
            body = "Hello <b> %s</b>,<br> \n\
            Welcome to Gluu Inc.! <br>\
            Please use this One Time Password (OTP) for your first-time login. After logging in, please create your own password.<h1>%s </h1> " %(uid, password)       
            sender = EmailSender()       
            sender.sendEmail(mail, subject, body)
            print("POST CREATE USER: OTP send successfully")
            break

        return True

    def postUpdateUser(self, user, configurationAttributes):
        return True

    def postDeleteUser(self, user, configurationAttributes):
        return True

    def postUpdateGroup(self, group, configurationAttributes):
        return True

    def postCreateGroup(self, group, configurationAttributes):
        return True

    def postDeleteGroup(self, group, configurationAttributes):
        return True

    def getUser(self, user, configurationAttributes):
        return True

    def getGroup(self, group, configurationAttributes):
        return True

    def postSearchUsers(self, results, configurationAttributes):
        return True

    def postSearchGroups(self, results, configurationAttributes):
        return True

    def allowResourceOperation(self, context, entity, configurationAttributes):
        return True 

    def allowSearchOperation(self, context, configurationAttributes):
        return ""

    def rejectedResourceOperationResponse(self, context, entity, configurationAttributes):
        return None       

    def rejectedSearchOperationResponse(self, context, configurationAttributes):
        return None

    def manageResourceOperation(self, context, entity, payload, configurationAttributes):
        return None

    def manageSearchOperation(self, context, searchRequest, configurationAttributes):
        return None

    class Otp:
    #class that deals with string token

    def generateOtp(self,lent):
        rand1="1234567890123456789123456789"
        rand2="9876543210123456789123456789"
        first = int(rand1[:int(lent)])
        first1 = int(rand2[:int(lent)])
        token = random.randint(first, first1)
        return token

class EmailSender():

    def getSmtpConfig(self):

        smtp_config = None
        smtpconfig = CdiUtil.bean(ConfigurationService).getConfiguration().getSmtpConfiguration()

        if smtpconfig is None:
            print "Sign Email - SMTP CONFIG DOESN'T EXIST - Please configure"

        else:
            encryptionService = CdiUtil.bean(EncryptionService)
            print("SMTP config: %s"%smtpconfig)
            smtp_config = {
                'host' : smtpconfig.getHost(),
                'port' : smtpconfig.getPort(),
                'user' : smtpconfig.getFromName(),
                'from' : smtpconfig.getFromEmailAddress(),
                'pwd_decrypted' : encryptionService.decrypt(smtpconfig.getSmtpAuthenticationAccountPassword()),
                'requires_authentication' : smtpconfig.isRequiresAuthentication(),
                'server_trust' : smtpconfig.isServerTrust()
            }

        return smtp_config

    def sendEmail(self,  useremail, subject, messageText):
        # server connection
        try:        
            smtpconfig = self.getSmtpConfig()

            properties = Properties()
            properties.setProperty("mail.smtp.host", smtpconfig['host'])
            properties.setProperty("mail.smtp.port", str(smtpconfig['port']))
            properties.setProperty("mail.smtp.starttls.enable", "true")
            session = Session.getDefaultInstance(properties)

            message = MimeMessage(session)
            message.setFrom(InternetAddress(smtpconfig['from']))
            message.addRecipient(Message.RecipientType.TO,InternetAddress(useremail))
            message.setSubject(subject)
            #message.setText(messageText)
            message.setContent(messageText, "text/html")

            transport = session.getTransport("smtp")
            transport.connect(properties.get("mail.smtp.host"),int(properties.get("mail.smtp.port")), smtpconfig['from'], smtpconfig['pwd_decrypted'])
            transport.sendMessage(message,message.getRecipients(Message.RecipientType.TO))

            transport.close()
        except Exception as e:
            print(e)   

Step 4: Navigate to the Scripts using Jans TUI and configure the following items

  • Make sure you have your SMTP settings correctly at Jans Server /opt/jans/jans-cli/jans-cli-tui.py then navigate to SMTP

  • Navigate to Scripts and Add Script
  • Set a custom attribute with key otp_length
  • Import above script
  • Enable the custom script.

It’s done. Let’s see the demo

[embed]

Thanks.


메타데이터
post_id
f4c638f2ced6
slug
welcome-email-for-newly-registered-users-over-scim-2-0-f4c638f2ced6
url
https://medium.com/@mmrraju/welcome-email-for-newly-registered-users-over-scim-2-0-f4c638f2ced6
canonical_url
https://medium.com/@mmrraju/welcome-email-for-newly-registered-users-over-scim-2-0-f4c638f2ced6
author_url
https://medium.com/@mmrraju
status
ok
fetched_at
2026-07-24 04:30:11