Skip to content

Instantly share code, notes, and snippets.

@imShakil
Created February 17, 2023 02:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imShakil/70a1ff8ddbe0affba93563d81519916d to your computer and use it in GitHub Desktop.
Save imShakil/70a1ff8ddbe0affba93563d81519916d to your computer and use it in GitHub Desktop.
from org.gluu.oxauth.service import AuthenticationService
from org.gluu.oxauth.service import UserService
from org.gluu.oxauth.auth import Authenticator
from org.gluu.oxauth.security import Identity
from org.gluu.model.custom.script.type.auth import PersonAuthenticationType
from org.gluu.service.cdi.util import CdiUtil
from org.gluu.util import StringHelper
from org.gluu.oxauth.util import ServerUtil
from org.gluu.oxauth.service.common import ConfigurationService
from org.gluu.oxauth.service.common import EncryptionService
from org.gluu.jsf2.message import FacesMessages
from javax.faces.application import FacesMessage
from org.gluu.persist.exception import AuthenticationException
from datetime import datetime, timedelta
from java.util import GregorianCalendar, TimeZone
from java.io import File
from java.io import FileInputStream
from java.util import Enumeration, Properties
#dealing with smtp server
from java.security import Security
from javax.mail.internet import MimeMessage, InternetAddress
from javax.mail import Session, Message, Transport
from java.util import Arrays
import random
import string
import re
import urllib
import java
try:
import json
except ImportError:
import simplejson as json
class EmailValidator():
regex = '^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'
def check(self, email):
if(re.search(self.regex,email)):
print "EmailOTP. - %s is a valid email format" % email
return True
else:
print "EmailOTP. - %s is an invalid email format" % email
return False
class Token:
#class that deals with string token
def generateToken(self,lent):
rand1="1234567890123456789123456789"
rand2="9876543210123456789123456789"
first = int(rand1[:int(lent)])
first1 = int(rand2[:int(lent)])
token = random.randint(first, first1)
return token
class PersonAuthentication(PersonAuthenticationType):
def __init__(self, currentTimeMillis):
self.currentTimeMillis = currentTimeMillis
def init(self, customScript, configurationAttributes):
print "EmailOTP. - Initialized successfully"
self.userName = ""
self.userPassword = ""
return True
def destroy(self, configurationAttributes):
print "EmailOTP. - Destroyed successfully"
return True
def getApiVersion(self):
return 11
def isValidAuthenticationMethod(self, usageType, configurationAttributes):
return True
def getAuthenticationMethodClaims(self, configurationAttributes):
return None
def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):
return None
def authenticate(self, configurationAttributes, requestParameters, step):
print "Email 2FA - Authenticate for step %s" % ( step)
authenticationService = CdiUtil.bean(AuthenticationService)
identity = CdiUtil.bean(Identity)
credentials = identity.getCredentials()
user_name = credentials.getUsername()
user_password = credentials.getPassword()
self.userName = user_name
self.userPassword = user_password
identity.setWorkingParameter("userName", user_name)
identity.setWorkingParameter("userPassword", user_password)
facesMessages = CdiUtil.bean(FacesMessages)
facesMessages.setKeepMessages()
if step == 1:
try:
# Check if user authenticated already in another custom script
user2 = authenticationService.getAuthenticatedUser()
if user2 == None:
credentials = identity.getCredentials()
user_name = credentials.getUsername()
user_password = credentials.getPassword()
logged_in = False
if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
userService = CdiUtil.bean(UserService)
logged_in = authenticationService.authenticate(user_name, user_password)
if logged_in is True:
print "email2FA: User logged in successfully"
user2 = authenticationService.getAuthenticatedUser()
find_user = userService.getUser(user_name)
user_mail = userService.getCustomAttribute(find_user, 'mail').getValue()
print ("print user mail %s" %user_mail)
return logged_in
except AuthenticationException as err:
print err
return False
else:
print "EmailOTP. - Step 2 is called here for otp validation"
user2 = authenticationService.getAuthenticatedUser()
token = identity.getWorkingParameter("token")
input_token = ServerUtil.getFirstValue(requestParameters, "ResetTokenForm:inputToken")
print "input token %s" % input_token
print "EmailOTP. - Token input by user is %s" % input_token
token = str(identity.getWorkingParameter("token"))
min11 = int(identity.getWorkingParameter("sentmin"))
nww = datetime.now()
te = str(nww)
listew = te.split(':')
curtime = int(listew[1])
token_lifetime = int(configurationAttributes.get("token_lifetime").getValue2())
if ((min11<= 60) and (min11>= 50)):
if ((curtime>=50) and (curtime<=60)):
timediff1 = curtime - min11
if timediff1>token_lifetime:
#print "OTP Expired"
facesMessages.add(FacesMessage.SEVERITY_ERROR, "OTP Expired")
return False
elif ((curtime>=0) or (curtime<=10)):
timediff1 = 60 - min11
timediff1 = timediff1 + curtime
if timediff1>token_lifetime:
#print "OTP Expired"
facesMessages.add(FacesMessage.SEVERITY_ERROR, "OTP Expired")
return False
if ((min11>=0) and (min11<=60) and (curtime>=0) and (curtime<=60)):
timediff2 = curtime - min11
if timediff2>token_lifetime:
#print "OTP Expired"
facesMessages.add(FacesMessage.SEVERITY_ERROR, "OTP Expired")
return False
# compares token sent and token entered by user
print "Token from session: %s " % token
if input_token == token:
print "Email 2FA - token entered correctly"
identity.setWorkingParameter("token_valid", True)
return True
else:
facesMessages = CdiUtil.bean(FacesMessages)
facesMessages.setKeepMessages()
facesMessages.clear()
facesMessages.add(FacesMessage.SEVERITY_ERROR, "Wrong code entered")
print "EmailOTP. Wrong code entered"
return False
def prepareForStep(self, configurationAttributes, requestParameters, step):
print "EmailOTP. - Preparing for step %s" % step
authenticationService = CdiUtil.bean(AuthenticationService)
user2 = authenticationService.getAuthenticatedUser()
userService = CdiUtil.bean(UserService)
if step == 2 and user2 is not None:
identity = CdiUtil.bean(Identity)
user_name = self.userName
lent = configurationAttributes.get("token_length").getValue2()
new_token = Token()
token = new_token.generateToken(lent)
subject = "Gluu Authentication Token"
body = "Here is your token: %s" % token
find_user = userService.getUser(user_name)
user_mail = userService.getCustomAttribute(find_user, 'mail').getValue()
print(user_mail)
sender = EmailSender()
sender.sendEmail(user_mail, subject, body)
print("Mail send done")
otptime1 = datetime.now()
tess = str(otptime1)
listee = tess.split(':')
identity.setWorkingParameter("sentmin", listee[1])
identity.setWorkingParameter("token", token)
return True
return True
def getExtraParametersForStep(self, configurationAttributes, step):
return Arrays.asList("token","emailIds","token_valid","sentmin")
def getCountAuthenticationSteps(self, configurationAttributes):
return 2
def getPageForStep(self, configurationAttributes, step):
print "EmailOTP. getPageForStep called %s" % step
if step == 2:
return "/auth/email_auth/entertoken.xhtml"
return ""
def getNextStep(self, configurationAttributes, requestParameters, step):
return -1
def logout(self, configurationAttributes, requestParameters):
return True
def getMaskedEmail (self, emailid):
regex = r"(?<=.)[^@\n](?=[^@\n]*?@)|(?:(?<=@.)|(?!^)\G(?=[^@\n]*$)).(?=.*\.)"
subst = "*"
result = re.sub(regex, subst, emailid, 0, re.MULTILINE)
if result:
print (result)
return result
class EmailSender():
#class that sends e-mail through smtp
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)
smtp_config = {
'host' : smtpconfig.getHost(),
'port' : smtpconfig.getPort(),
'user' : smtpconfig.getUserName(),
'from' : smtpconfig.getFromEmailAddress(),
'pwd_decrypted' : encryptionService.decrypt(smtpconfig.getPassword()),
'req_ssl' : smtpconfig.getConnectProtection(),
'requires_authentication' : smtpconfig.isRequiresAuthentication(),
'server_trust' : smtpconfig.isServerTrust()
}
return smtp_config
def sendEmail(self, useremail, subject, messageText):
# server connection
smtpconfig = self.getSmtpConfig()
print("Mail sever configuration Done")
properties = Properties()
properties.setProperty("mail.smtp.host", smtpconfig['host'])
properties.setProperty("mail.smtp.port", str(smtpconfig['port']))
if smtpconfig['requires_authentication']:
properties.setProperty("mail.smtp.auth", "true")
if smtpconfig['req_ssl'] is not None:
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['user'], smtpconfig['pwd_decrypted'])
transport.sendMessage(message,message.getRecipients(Message.RecipientType.TO))
print("Send mail")
transport.close()
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
template="/WEB-INF/incl/layout/template.xhtml">
<f:metadata>
<f:viewAction action="#{authenticator.prepareAuthenticationForStep}" if="#{not identity.loggedIn}"/>
</f:metadata>
<ui:define name="head">
<meta name="description" content="Gluu Inc." />
<!-- Here we use # {...} which are JSF EL expressions, they bind server values to this markup -->
<link href="#{oxAuthConfigurationService.getCssLocation()}/bootstrap.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="#{oxAuthConfigurationService.getCssLocation()}/style.css"/>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600" rel="stylesheet"/>
</ui:define>
<ui:define name="body">
<!-- this is copy pasted from somewhere ... -->
<header class="bs-docs-nav navbar navbar-static-top" id="top">
<div class="container">
<div class="navbar-header">
<a target="_blank" class="navbar-brand">
<ui:param name="client" value="#{clientService.getClient(redirect.parameters['client_id'])}" />
<h:panelGroup rendered='#{!empty client.getLogoUri()}'>
<h:graphicImage url='#{client.getLogoUri()}'/>
</h:panelGroup> </a>
</div>
</div>
</header>
<h:form id="ResetTokenForm">
<div class="bs-docs-section">
<div class="container">
<div class="step_bx">
<h2>Authentication Token</h2>
<p>Enter the token received in your email</p>
<!-- This form field is referenced in authenticate method of script -->
<input class="form-control" id="ResetTokenForm:inputToken" name="ResetTokenForm:inputToken"
type="text" autocomplete="off" />
<h:commandButton class="btn btn-done" value="Submit"
action="#{authenticator.authenticate}" />
</div>
</div>
</div>
</h:form>
<script type="text/javascript">
window.onload = start;
function start() {
func1();
}
function func1() {
user_email = `#{identity.sessionId.sessionAttributes['useremail']}`;
var avg, temp, splitted, part1, part2;
splitted = user_email.split("@");
part1 = splitted[0];
temp = part1.length - 3;
part1 = part1.substring(temp, part1.length);
part2 = splitted[1];
avg = "..." + part1 + "@" + part2;
var text = document.getElementById("msg");
text.innerHTML = avg;
}
</script>
</ui:define>
</ui:composition>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment