mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
QQQ-27: updates to allow Auth0 to be an authentication model in QQQ
This commit is contained in:
5
pom.xml
5
pom.xml
@ -53,6 +53,11 @@
|
||||
<!-- none, this is core. -->
|
||||
|
||||
<!-- 3rd party deps specifically for this module -->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>mvc-auth-commons</artifactId>
|
||||
<version>[1.0, 2.0)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.exceptions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Exception thrown while doing module-dispatch
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QAuthenticationException extends QException
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor of message
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAuthenticationException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor of message & cause
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAuthenticationException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Enum to define the possible authentication types
|
||||
**
|
||||
*******************************************************************************/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public enum QAuthenticationType
|
||||
{
|
||||
AUTH_0("auth0"),
|
||||
FULLY_ANONYMOUS("fullyAnonymous"),
|
||||
MOCK("mock");
|
||||
|
||||
private final String name;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** enum constructor
|
||||
*******************************************************************************/
|
||||
QAuthenticationType(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
@ -32,6 +32,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleVal
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.QAuthenticationMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -22,6 +22,7 @@
|
||||
package com.kingsrook.qqq.backend.core.model.session;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -29,7 +30,7 @@ import java.util.Map;
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QSession
|
||||
public class QSession implements Serializable
|
||||
{
|
||||
private String idReference;
|
||||
private QUser user;
|
||||
|
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import com.auth0.jwk.Jwk;
|
||||
import com.auth0.jwk.JwkException;
|
||||
import com.auth0.jwk.JwkProvider;
|
||||
import com.auth0.jwk.UrlJwkProvider;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.exceptions.TokenExpiredException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwt.interfaces.JWTVerifier;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.Auth0AuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.state.AbstractStateKey;
|
||||
import com.kingsrook.qqq.backend.core.state.InMemoryStateProvider;
|
||||
import com.kingsrook.qqq.backend.core.state.StateProviderInterface;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
{
|
||||
private static final Logger logger = LogManager.getLogger(Auth0AuthenticationModule.class);
|
||||
|
||||
private static final int ID_TOKEN_VALIDATION_INTERVAL_SECONDS = 300;
|
||||
|
||||
public static final String AUTH0_ID_TOKEN_KEY = "qqq.idToken";
|
||||
|
||||
public static final String TOKEN_NOT_PROVIDED_ERROR = "Id Token was not provided";
|
||||
public static final String COULD_NOT_DECODE_ERROR = "Unable to decode id token";
|
||||
public static final String EXPIRED_TOKEN_ERROR = "Token has expired";
|
||||
public static final String INVALID_TOKEN_ERROR = "An invalid token was provided";
|
||||
|
||||
|
||||
private Instant now;
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public QSession createSession(QInstance qInstance, Map<String, String> context) throws QAuthenticationException
|
||||
{
|
||||
//////////////////////////////////////////////////
|
||||
// get the jwt id token from the context object //
|
||||
//////////////////////////////////////////////////
|
||||
String idToken = context.get(AUTH0_ID_TOKEN_KEY);
|
||||
if(idToken == null)
|
||||
{
|
||||
////////////////////////////////
|
||||
// could not decode the token //
|
||||
////////////////////////////////
|
||||
logger.warn(TOKEN_NOT_PROVIDED_ERROR);
|
||||
throw (new QAuthenticationException(TOKEN_NOT_PROVIDED_ERROR));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// decode the token locally to make sure it is valid and to look at when it expires //
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
try
|
||||
{
|
||||
/////////////////////////////////////////////////////
|
||||
// try to build session to see if still valid //
|
||||
// then call method to check more session validity //
|
||||
/////////////////////////////////////////////////////
|
||||
QSession qSession = buildQSessionFromToken(idToken);
|
||||
if(isSessionValid(qSession))
|
||||
{
|
||||
return (qSession);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// if we make it here it means we have never validated this token or its been a long //
|
||||
// enough duration so we need to re-verify the token //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
qSession = revalidateToken(qInstance, idToken);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// put now into state so we dont check until next interval passes //
|
||||
///////////////////////////////////////////////////////////////////
|
||||
StateProviderInterface spi = getStateProvider();
|
||||
Auth0StateKey key = new Auth0StateKey(qSession.getIdReference());
|
||||
spi.put(key, getNow());
|
||||
|
||||
return (qSession);
|
||||
}
|
||||
catch(JWTDecodeException jde)
|
||||
{
|
||||
////////////////////////////////
|
||||
// could not decode the token //
|
||||
////////////////////////////////
|
||||
logger.warn(COULD_NOT_DECODE_ERROR, jde);
|
||||
throw (new QAuthenticationException(COULD_NOT_DECODE_ERROR));
|
||||
}
|
||||
catch(TokenExpiredException tee)
|
||||
{
|
||||
logger.info(EXPIRED_TOKEN_ERROR, tee);
|
||||
throw (new QAuthenticationException(EXPIRED_TOKEN_ERROR));
|
||||
}
|
||||
catch(JWTVerificationException | JwkException jve)
|
||||
{
|
||||
///////////////////////////////////////////
|
||||
// token had invalid signature or claims //
|
||||
///////////////////////////////////////////
|
||||
logger.warn(INVALID_TOKEN_ERROR, jve);
|
||||
throw (new QAuthenticationException(INVALID_TOKEN_ERROR));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
////////////////
|
||||
// ¯\_(ツ)_/¯ //
|
||||
////////////////
|
||||
String message = "An unknown error occurred";
|
||||
logger.error(message, e);
|
||||
throw (new QAuthenticationException(message));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public boolean isSessionValid(QSession session)
|
||||
{
|
||||
if(session == null)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
|
||||
StateProviderInterface spi = getStateProvider();
|
||||
Auth0StateKey key = new Auth0StateKey(session.getIdReference());
|
||||
if(spi.get(Instant.class, key).isPresent())
|
||||
{
|
||||
Instant lastTimeChecked = spi.get(Instant.class, key).get();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// returns negative int if less than compared duration, 0 if equal, positive int if greater than //
|
||||
// - so this is basically saying, if the time between the last time we checked the token and //
|
||||
// right now is more than ID_TOKEN_VALIDATION_INTERVAL_SECTIONS, then session needs revalidated //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
return (Duration.between(lastTimeChecked, getNow()).compareTo(Duration.ofSeconds(ID_TOKEN_VALIDATION_INTERVAL_SECONDS)) < 0);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** public method so that 'now' can be used for testing purposes
|
||||
** - defaults to real 'now'
|
||||
*******************************************************************************/
|
||||
public Instant getNow()
|
||||
{
|
||||
if(now == null)
|
||||
{
|
||||
now = Instant.now();
|
||||
}
|
||||
|
||||
return (now);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** public method so that 'now' can be set for testing purposes
|
||||
*******************************************************************************/
|
||||
public void setNow(Instant now)
|
||||
{
|
||||
this.now = now;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** makes request to check if a token is still valid and build new qSession if it is
|
||||
**
|
||||
*******************************************************************************/
|
||||
private QSession revalidateToken(QInstance qInstance, String idToken) throws JwkException
|
||||
{
|
||||
Auth0AuthenticationMetaData metaData = (Auth0AuthenticationMetaData) qInstance.getAuthentication();
|
||||
|
||||
DecodedJWT jwt = JWT.decode(idToken);
|
||||
JwkProvider provider = new UrlJwkProvider(metaData.getBaseUrl());
|
||||
Jwk jwk = provider.get(jwt.getKeyId());
|
||||
Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withIssuer(metaData.getBaseUrl())
|
||||
.build();
|
||||
|
||||
///////////////////////////////////
|
||||
// make call to verify the token //
|
||||
///////////////////////////////////
|
||||
verifier.verify(idToken);
|
||||
|
||||
return (buildQSessionFromToken(idToken));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** extracts info from token creating a QSession
|
||||
**
|
||||
*******************************************************************************/
|
||||
private QSession buildQSessionFromToken(String idToken) throws JwkException
|
||||
{
|
||||
////////////////////////////////////
|
||||
// decode and extract the payload //
|
||||
////////////////////////////////////
|
||||
DecodedJWT jwt = JWT.decode(idToken);
|
||||
Base64.Decoder decoder = Base64.getUrlDecoder();
|
||||
String payloadString = new String(decoder.decode(jwt.getPayload()));
|
||||
JSONObject payload = new JSONObject(payloadString);
|
||||
|
||||
QUser qUser = new QUser();
|
||||
qUser.setIdReference(payload.getString("email"));
|
||||
qUser.setFullName(payload.getString("name"));
|
||||
|
||||
QSession qSession = new QSession();
|
||||
qSession.setIdReference(idToken);
|
||||
qSession.setUser(qUser);
|
||||
|
||||
return (qSession);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Load an instance of the appropriate state provider
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static StateProviderInterface getStateProvider()
|
||||
{
|
||||
// TODO - read this from somewhere in meta data eh?
|
||||
return (InMemoryStateProvider.getInstance());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static class Auth0StateKey extends AbstractStateKey
|
||||
{
|
||||
private final String key;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor.
|
||||
**
|
||||
*******************************************************************************/
|
||||
Auth0StateKey(String key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return (this.key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(this == o)
|
||||
return true;
|
||||
if(o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Auth0StateKey that = (Auth0StateKey) o;
|
||||
return key.equals(that.key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return key.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
@ -24,9 +24,9 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -40,7 +40,7 @@ public class FullyAnonymousAuthenticationModule implements QAuthenticationModule
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public QSession createSession(Map<String, String> context)
|
||||
public QSession createSession(QInstance qInstance, Map<String, String> context)
|
||||
{
|
||||
QUser qUser = new QUser();
|
||||
qUser.setIdReference("anonymous");
|
||||
@ -68,10 +68,6 @@ public class FullyAnonymousAuthenticationModule implements QAuthenticationModule
|
||||
@Override
|
||||
public boolean isSessionValid(QSession session)
|
||||
{
|
||||
if(session == null)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
return session != null;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -43,7 +44,7 @@ public class MockAuthenticationModule implements QAuthenticationModuleInterface
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public QSession createSession(Map<String, String> context)
|
||||
public QSession createSession(QInstance qInstance, Map<String, String> context)
|
||||
{
|
||||
QUser qUser = new QUser();
|
||||
qUser.setIdReference("User:" + (System.currentTimeMillis() % USER_ID_MODULO));
|
||||
|
@ -25,8 +25,8 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.QAuthenticationMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -38,7 +38,7 @@ import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModu
|
||||
*******************************************************************************/
|
||||
public class QAuthenticationModuleDispatcher
|
||||
{
|
||||
private Map<String, String> authenticationTypeToModuleClassNameMap;
|
||||
private final Map<String, String> authenticationTypeToModuleClassNameMap;
|
||||
|
||||
|
||||
|
||||
@ -48,9 +48,9 @@ public class QAuthenticationModuleDispatcher
|
||||
public QAuthenticationModuleDispatcher()
|
||||
{
|
||||
authenticationTypeToModuleClassNameMap = new HashMap<>();
|
||||
authenticationTypeToModuleClassNameMap.put("mock", "com.kingsrook.qqq.backend.core.modules.authentication.MockAuthenticationModule");
|
||||
authenticationTypeToModuleClassNameMap.put("fullyAnonymous", "com.kingsrook.qqq.backend.core.modules.authentication.FullyAnonymousAuthenticationModule");
|
||||
authenticationTypeToModuleClassNameMap.put("TODO:google", "com.kingsrook.qqq.authentication.module.google.GoogleAuthenticationModule");
|
||||
authenticationTypeToModuleClassNameMap.put(QAuthenticationType.MOCK.getName(), "com.kingsrook.qqq.backend.core.modules.authentication.MockAuthenticationModule");
|
||||
authenticationTypeToModuleClassNameMap.put(QAuthenticationType.FULLY_ANONYMOUS.getName(), "com.kingsrook.qqq.backend.core.modules.authentication.FullyAnonymousAuthenticationModule");
|
||||
authenticationTypeToModuleClassNameMap.put(QAuthenticationType.AUTH_0.getName(), "com.kingsrook.qqq.backend.core.modules.authentication.Auth0AuthenticationModule");
|
||||
// todo - let user define custom type -> classes
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ public class QAuthenticationModuleDispatcher
|
||||
throw (new QModuleDispatchException("No authentication meta data defined."));
|
||||
}
|
||||
|
||||
return getQModule(authenticationMetaData.getType());
|
||||
return getQModule(authenticationMetaData.getType().getName());
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,8 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
|
||||
|
||||
@ -35,7 +37,7 @@ public interface QAuthenticationModuleInterface
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
QSession createSession(Map<String, String> context);
|
||||
QSession createSession(QInstance qInstance, Map<String, String> context) throws QAuthenticationException;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.modules.authentication.metadata;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Meta-data to provide details of an RDBMS backend (e.g., connection params)
|
||||
*******************************************************************************/
|
||||
public class Auth0AuthenticationMetaData extends QAuthenticationMetaData
|
||||
{
|
||||
private String baseUrl;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Default Constructor.
|
||||
*******************************************************************************/
|
||||
public Auth0AuthenticationMetaData()
|
||||
{
|
||||
super();
|
||||
setType(QAuthenticationType.AUTH_0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter, override to help fluent flows
|
||||
*******************************************************************************/
|
||||
public Auth0AuthenticationMetaData withBaseUrl(String baseUrl)
|
||||
{
|
||||
setBaseUrl(baseUrl);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for baseUrl
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getBaseUrl()
|
||||
{
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for baseUrl
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setBaseUrl(String baseUrl)
|
||||
{
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
}
|
@ -19,12 +19,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
package com.kingsrook.qqq.backend.core.modules.authentication.metadata;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.fasterxml.jackson.annotation.JsonFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -35,7 +36,7 @@ import com.fasterxml.jackson.annotation.JsonFilter;
|
||||
public class QAuthenticationMetaData
|
||||
{
|
||||
private String name;
|
||||
private String type;
|
||||
private QAuthenticationType type;
|
||||
|
||||
@JsonFilter("secretsFilter")
|
||||
private Map<String, String> values;
|
||||
@ -120,7 +121,7 @@ public class QAuthenticationMetaData
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
public QAuthenticationType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
@ -131,7 +132,7 @@ public class QAuthenticationMetaData
|
||||
** Setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setType(String type)
|
||||
public void setType(QAuthenticationType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
@ -141,7 +142,7 @@ public class QAuthenticationMetaData
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAuthenticationMetaData withType(String type)
|
||||
public QAuthenticationMetaData withType(QAuthenticationType type)
|
||||
{
|
||||
this.type = type;
|
||||
return (this);
|
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.Auth0AuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static com.kingsrook.qqq.backend.core.modules.authentication.Auth0AuthenticationModule.AUTH0_ID_TOKEN_KEY;
|
||||
import static com.kingsrook.qqq.backend.core.modules.authentication.Auth0AuthenticationModule.COULD_NOT_DECODE_ERROR;
|
||||
import static com.kingsrook.qqq.backend.core.modules.authentication.Auth0AuthenticationModule.EXPIRED_TOKEN_ERROR;
|
||||
import static com.kingsrook.qqq.backend.core.modules.authentication.Auth0AuthenticationModule.INVALID_TOKEN_ERROR;
|
||||
import static com.kingsrook.qqq.backend.core.modules.authentication.Auth0AuthenticationModule.TOKEN_NOT_PROVIDED_ERROR;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for the FullyAnonymousAuthenticationModule
|
||||
*******************************************************************************/
|
||||
public class Auth0AuthenticationModuleTest
|
||||
{
|
||||
private static final String VALID_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IllrY2FkWTA0Q3RFVUFxQUdLNTk3ayJ9.eyJnaXZlbl9uYW1lIjoiVGltIiwiZmFtaWx5X25hbWUiOiJDaGFtYmVybGFpbiIsIm5pY2tuYW1lIjoidGltLmNoYW1iZXJsYWluIiwibmFtZSI6IlRpbSBDaGFtYmVybGFpbiIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQUZkWnVjcXVSaUFvTzk1RG9URklnbUtseVA1akVBVnZmWXFnS0lHTkVubzE9czk2LWMiLCJsb2NhbGUiOiJlbiIsInVwZGF0ZWRfYXQiOiIyMDIyLTA3LTE5VDE2OjI0OjQ1LjgyMloiLCJlbWFpbCI6InRpbS5jaGFtYmVybGFpbkBraW5nc3Jvb2suY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8va2luZ3Nyb29rLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDEwODk2NDEyNjE3MjY1NzAzNDg2NyIsImF1ZCI6InNwQ1NtczAzcHpVZGRYN1BocHN4ZDlUd2FLMDlZZmNxIiwiaWF0IjoxNjU4MjQ3OTAyLCJleHAiOjE2NTgyODM5MDIsIm5vbmNlIjoiZUhOdFMxbEtUR2N5ZG5KS1VVY3RkRTFVT0ZKNmJFNUxVVkEwZEdsRGVXOXZkVkl4UW41eVRrUlJlZz09In0.hib7JR8NDU2kx8Fj1bnzo3IUuabE6Hb-Z7HHZAJPQuF_Zdg3L1KDypn6SY7HAd_dsz2N8RkXfvQto-Y2g2ukuz7FxzNFgcVL99cyEO3YqmyCa6JTOTCrxdeaIE8QZpCEKvC28oeJBv0wO1Dwc--OVJMsK2vSzyxj1WNok64YYjWKLL4c0dFf-nj0KWFr1IU-tMiyWLDDiJw2Sa8M4YxXZYqdlkgNmrBPExgcm9l9SiT2l3Ts3Sgc_IyMVyMrnV8XX50EWdsm6vuCOSUcqf0XhjDQ7urZveoVwVLnYq3GcLhVBcy1Hr9RL8zPdPynOzsbX6uCww2Esrv6iwWrgQ5zBA";
|
||||
private static final String INVALID_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IllrY2FkWTA0Q3RFVUFxQUdLNTk3ayJ9.eyJnaXZlbl9uYW1lIjoiVGltIiwiZmFtaWx5X25hbWUiOiJDaGFtYmVybGFpbiIsIm5pY2tuYW1lIjoidGltLmNoYW1iZXJsYWluIiwibmFtZSI6IlRpbSBDaGFtYmVybGFpbiIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQUZkWnVjcXVSaUFvTzk1RG9URklnbUtseVA1akVBVnZmWXFnS0lHTkVubzE9czk2LWMiLCJsb2NhbGUiOiJlbiIsInVwZGF0ZWRfYXQiOiIyMDIyLTA3LTE5VDE2OjI0OjQ1LjgyMloiLCJlbWFpbCI6InRpbS5jaGFtYmVybGFpbkBraW5nc3Jvb2suY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8va2luZ3Nyb29rLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDEwODk2NDEyNjE3MjY1NzAzNDg2NyIsImF1ZCI6InNwQ1NtczAzcHpVZGRYN1BocHN4ZDlUd2FLMDlZZmNxIiwiaWF0IjoxNjU4MjQ3OTAyLCJleHAiOjE2NTgyODM5MDIsIm5vbmNlIjoiZUhOdFMxbEtUR2N5ZG5KS1VVY3RkRTFVT0ZKNmJFNUxVVkEwZEdsRGVXOXZkVkl4UW41eVRrUlJlZz09In0.hib7JR8NDU2kx8Fj1bnzo3IUuabE6Hb-Z7HHZAJPQuF_Zdg3L1KDypn6SY7HAd_dsz2N8RkXfvQto-Y2g2ukuz7FxzNFgcVL99cyEO3YqmyCa6JTOTCrxdeaIE8QZpCEKvC28oeJBv0wO1Dwc--OVJMsK2vSzyxj1WNok64YYjWKLL4c0dFf-nj0KWFr1IU-tMiyWLDDiJw2Sa8M4YxXZYqdlkgNmrBPExgcm9l9SiT2l3Ts3Sgc_IyMVyMrnV8XX50EWdsm6vuCOSUcqf0XhjDQ7urZveoVwVLnYq3GcLhVBcy1Hr9RL8zPdPynOzsbX6uCww2Esrv6iwWrgQ5zBA-thismakesinvalid";
|
||||
private static final String EXPIRED_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IllrY2FkWTA0Q3RFVUFxQUdLNTk3ayJ9.eyJnaXZlbl9uYW1lIjoiVGltIiwiZmFtaWx5X25hbWUiOiJDaGFtYmVybGFpbiIsIm5pY2tuYW1lIjoidGltLmNoYW1iZXJsYWluIiwibmFtZSI6IlRpbSBDaGFtYmVybGFpbiIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQUZkWnVjcXVSaUFvTzk1RG9URklnbUtseVA1akVBVnZmWXFnS0lHTkVubzE9czk2LWMiLCJsb2NhbGUiOiJlbiIsInVwZGF0ZWRfYXQiOiIyMDIyLTA3LTE4VDIxOjM4OjE1LjM4NloiLCJlbWFpbCI6InRpbS5jaGFtYmVybGFpbkBraW5nc3Jvb2suY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8va2luZ3Nyb29rLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDEwODk2NDEyNjE3MjY1NzAzNDg2NyIsImF1ZCI6InNwQ1NtczAzcHpVZGRYN1BocHN4ZDlUd2FLMDlZZmNxIiwiaWF0IjoxNjU4MTgwNDc3LCJleHAiOjE2NTgyMTY0NzcsIm5vbmNlIjoiVkZkQlYzWmplR2hvY1cwMk9WZEtabHBLU0c1K1ZXbElhMEV3VkZaeFpVdEJVMDErZUZaT1RtMTNiZz09In0.fU7EwUgNrupOPz_PX_aQKON2xG1-LWD85xVo1Bn41WNEek-iMyJoch8l6NUihi7Bou14BoOfeWIG_sMqsLHqI2Pk7el7l1kigsjURx0wpiXadBt8piMxdIlxdToZEMuZCBzg7eJvXh4sM8tlV5cm0gPa6FT9Ih3VGJajNlXi5BcYS_JRpIvFvHn8-Bxj4KiAlZ5XPPkopjnDgP8kFfc4cMn_nxDkqWYlhj-5TaGW2xCLC9Qr_9UNxX0fm-CkKjYs3Z5ezbiXNkc-bxrCYvxeBeDPf8-T3EqrxCRVqCZSJ85BHdOc_E7UZC_g8bNj0umoplGwlCbzO4XIuOO-KlIaOg";
|
||||
private static final String UNDECODABLE_TOKEN = "UNDECODABLE";
|
||||
|
||||
public static final String AUTH0_BASE_URL = "https://kingsrook.us.auth0.com/";
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test a valid token where 'now' is set to a time that would be valid for it
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testValidToken() throws QAuthenticationException
|
||||
{
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put(AUTH0_ID_TOKEN_KEY, VALID_TOKEN);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// Tuesday, July 19, 2022 12:40:27.299 PM GMT-05:00 DST //
|
||||
//////////////////////////////////////////////////////////
|
||||
Instant now = Instant.ofEpochMilli(1658252427299L);
|
||||
|
||||
Auth0AuthenticationModule auth0AuthenticationModule = new Auth0AuthenticationModule();
|
||||
auth0AuthenticationModule.setNow(now);
|
||||
QSession session = auth0AuthenticationModule.createSession(getQInstance(), context);
|
||||
assertTrue(session.getUser().getIdReference().equals("tim.chamberlain@kingsrook.com"));
|
||||
assertTrue(session.getUser().getFullName().equals("Tim Chamberlain"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test failure case, token is invalid
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testInvalidToken()
|
||||
{
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put(AUTH0_ID_TOKEN_KEY, INVALID_TOKEN);
|
||||
|
||||
try
|
||||
{
|
||||
Auth0AuthenticationModule auth0AuthenticationModule = new Auth0AuthenticationModule();
|
||||
auth0AuthenticationModule.createSession(getQInstance(), context);
|
||||
}
|
||||
catch(QAuthenticationException qae)
|
||||
{
|
||||
assertTrue(qae.getMessage().contains(INVALID_TOKEN_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Should never get here");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test failure case, token cant be decoded
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testUndecodableToken()
|
||||
{
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put(AUTH0_ID_TOKEN_KEY, UNDECODABLE_TOKEN);
|
||||
|
||||
try
|
||||
{
|
||||
Auth0AuthenticationModule auth0AuthenticationModule = new Auth0AuthenticationModule();
|
||||
auth0AuthenticationModule.createSession(getQInstance(), context);
|
||||
}
|
||||
catch(QAuthenticationException qae)
|
||||
{
|
||||
assertTrue(qae.getMessage().contains(COULD_NOT_DECODE_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Should never get here");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test failure case, token is expired
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testProperlyFormattedButExpiredToken()
|
||||
{
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put(AUTH0_ID_TOKEN_KEY, EXPIRED_TOKEN);
|
||||
|
||||
try
|
||||
{
|
||||
Auth0AuthenticationModule auth0AuthenticationModule = new Auth0AuthenticationModule();
|
||||
auth0AuthenticationModule.createSession(getQInstance(), context);
|
||||
}
|
||||
catch(QAuthenticationException qae)
|
||||
{
|
||||
assertTrue(qae.getMessage().contains(EXPIRED_TOKEN_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Should never get here");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test failure case, empty context
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testEmptyContext()
|
||||
{
|
||||
try
|
||||
{
|
||||
Auth0AuthenticationModule auth0AuthenticationModule = new Auth0AuthenticationModule();
|
||||
auth0AuthenticationModule.createSession(getQInstance(), new HashMap<>());
|
||||
}
|
||||
catch(QAuthenticationException qae)
|
||||
{
|
||||
assertTrue(qae.getMessage().contains(TOKEN_NOT_PROVIDED_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Should never get here");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test failure case, null token
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testNullToken()
|
||||
{
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put(AUTH0_ID_TOKEN_KEY, null);
|
||||
|
||||
try
|
||||
{
|
||||
Auth0AuthenticationModule auth0AuthenticationModule = new Auth0AuthenticationModule();
|
||||
auth0AuthenticationModule.createSession(getQInstance(), context);
|
||||
}
|
||||
catch(QAuthenticationException qae)
|
||||
{
|
||||
assertTrue(qae.getMessage().contains(TOKEN_NOT_PROVIDED_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Should never get here");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** utility method to prime a qInstance for auth0 tests
|
||||
**
|
||||
*******************************************************************************/
|
||||
private QInstance getQInstance()
|
||||
{
|
||||
QAuthenticationMetaData authenticationMetaData = new Auth0AuthenticationMetaData()
|
||||
.withBaseUrl(AUTH0_BASE_URL)
|
||||
.withName("auth0");
|
||||
|
||||
QInstance qInstance = TestUtils.defineInstance();
|
||||
qInstance.setAuthentication(authenticationMetaData);
|
||||
return (qInstance);
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.FullyAnonymousAuthenticationModule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
@ -36,12 +35,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
public class FullyAnonymousAuthenticationModuleTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
FullyAnonymousAuthenticationModule fullyAnonymousAuthenticationModule = new FullyAnonymousAuthenticationModule();
|
||||
|
||||
QSession session = fullyAnonymousAuthenticationModule.createSession(null);
|
||||
QSession session = fullyAnonymousAuthenticationModule.createSession(null, null);
|
||||
|
||||
assertNotNull(session, "Session should not be null");
|
||||
assertNotNull(session.getIdReference(), "Session id ref should not be null");
|
||||
|
@ -23,9 +23,7 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleDispatcher;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
@ -26,8 +26,9 @@ import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.actions.processes.person.addtopeoplesage.AddAge;
|
||||
import com.kingsrook.qqq.backend.core.actions.processes.person.addtopeoplesage.GetAgeStatistics;
|
||||
import com.kingsrook.qqq.backend.core.adapters.QInstanceAdapter;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.mock.MockBackendStep;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.metadata.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
|
||||
@ -109,7 +110,7 @@ public class TestUtils
|
||||
{
|
||||
return new QAuthenticationMetaData()
|
||||
.withName("mock")
|
||||
.withType("mock");
|
||||
.withType(QAuthenticationType.MOCK);
|
||||
}
|
||||
|
||||
|
||||
@ -304,6 +305,6 @@ public class TestUtils
|
||||
public static QSession getMockSession()
|
||||
{
|
||||
MockAuthenticationModule mockAuthenticationModule = new MockAuthenticationModule();
|
||||
return (mockAuthenticationModule.createSession(null));
|
||||
return (mockAuthenticationModule.createSession(null, null));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user