Commit 8441bf57 by Tuukka Kivilahti

Merge branch 'hostname-to-username' into 'master'

Move hostname from BortalLocalContextHolder to jaas username

See merge request !377
2 parents 30568e17 0ced1669
Showing with 260 additions and 310 deletions
......@@ -29,8 +29,6 @@ public interface MoyaRealmBeanRemote {
Enumeration<String> getGroupNames(String user);
boolean authenticate(String _username, String string);
AuthenticationResult authUsername(String _username, String string);
Enumeration<String> getGroupNames(String username, String usertype);
......
......@@ -32,8 +32,6 @@ import fi.codecrew.moya.model.LanEventPropertyKey;
public interface EventBeanLocal {
// static final String HTTP_URL_HOSTNAME = "HTTP_URL_HOSTNAME";
LanEvent getEventByHostname(String hostname);
LanEvent getCurrentEvent();
LanEvent mergeChanges(LanEvent event);
......
......@@ -40,9 +40,6 @@ public interface PermissionBeanLocal {
// throws PermissionDeniedException;
// void fatalNotLoggedIn();
String getPrincipal();
/**
* Get common name of the logged in cert like "customer-01"
*
......@@ -62,6 +59,8 @@ public interface PermissionBeanLocal {
boolean isCurrentUser(String login);
String getPrincipalName();
// boolean hasPermission(String perm);
}
......@@ -42,11 +42,11 @@ public interface SessionMgmtBeanLocal {
UserContainer getUsername(String sessionId);
public static class UserContainer {
private final String hostname;
private final String hostname = "";
private final String username;
public UserContainer(String hostname, String username) {
this.hostname = hostname;
public UserContainer(String username) {
// this.hostname = hostname;
this.username = username;
}
......
......@@ -29,17 +29,12 @@ import org.slf4j.LoggerFactory;
import fi.codecrew.moya.enums.apps.IAppPermission;
public class BortalLocalContextHolder {
private static final ThreadLocal<BortalLocalContextHolder> THREAD_WITH_CONTEXT = new ThreadLocal<BortalLocalContextHolder>();
private String hostname;
private boolean ssl = false;
private Integer hostnameId;
private LoginContext loginContext;
private final Map<IAppPermission, Boolean> rightcache = new HashMap<IAppPermission, Boolean>();
private static boolean inDevelopmentMode = false;
......@@ -51,37 +46,13 @@ public class BortalLocalContextHolder {
private BortalLocalContextHolder(BortalLocalContextHolder old) {
super();
this.hostname = old.hostname;
this.ssl = old.ssl;
this.loginContext = old.loginContext;
}
public static void setHostname(String hostname) {
getThread().hostname = hostname;
}
public static String getHostname() {
return getThread().getHolderHostname();
}
public static void cleanupThread() {
if (THREAD_WITH_CONTEXT != null) {
THREAD_WITH_CONTEXT.remove();
}
}
public String getHolderHostname() {
return hostname;
}
public static Boolean hasPermission(IAppPermission permission) {
return getThread().hasHolderPermission(permission);
}
private static BortalLocalContextHolder getThread() {
......@@ -91,14 +62,6 @@ public class BortalLocalContextHolder {
return THREAD_WITH_CONTEXT.get();
}
private Boolean hasHolderPermission(IAppPermission target) {
return rightcache.get(target);
}
public static void setPermission(IAppPermission permission, Boolean value) {
getThread().rightcache.put(permission, value);
}
public static BortalLocalContextHolder getInstance() {
return getThread();
}
......@@ -111,54 +74,12 @@ public class BortalLocalContextHolder {
inDevelopmentMode = developmentMode;
}
public static Integer getHostnameId() {
return getThread().hostnameId;
}
public static void setHostnameId(Integer id)
{
getThread().hostnameId = id;
}
public static boolean isSsl() {
return getThread().ssl;
}
public static void setSsl(boolean ssl) {
getThread().ssl = ssl;
}
public static void copy(BortalLocalContextHolder contextHolder) {
if (THREAD_WITH_CONTEXT.get() != null) {
logger.warn("Context for thread is not empty. Received hostname {}", THREAD_WITH_CONTEXT.get().hostname);
logger.warn("Context for thread is not empty. Received hostname ");
}
THREAD_WITH_CONTEXT.set(new BortalLocalContextHolder(contextHolder));
}
public void setLoginContext(LoginContext loginContext) {
this.loginContext = loginContext;
}
public LoginContext getLoginContext() {
return loginContext;
}
public boolean executeLogin() {
try {
this.loginContext.login();
System.err.println("execute login");
return true;
} catch (LoginException e) {
return false;
}
}
public void executeLogout() {
try {
this.loginContext.logout();
System.err.println("execute logout");
} catch(Exception e) {
}
}
}
\ No newline at end of file
......@@ -82,7 +82,7 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal {
String authname = permissionBean.getCurrentUser().getLogin() + "_" + application.getName() + "_" + eventName;
while (instanceFacade.findInstance(application, authname) != null) {
while (instanceFacade.findInstance(application, authname, eventBean.getCurrentEvent()) != null) {
authname += "_";
}
......
......@@ -60,7 +60,6 @@ import org.xml.sax.SAXException;
import fi.codecrew.moya.checkoutfi.CheckoutFiCheckParam;
import fi.codecrew.moya.checkoutfi.CheckoutFiPaymentParam;
import fi.codecrew.moya.checkoutfi.CheckoutQueryParam;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.enums.apps.BillPermission;
import fi.codecrew.moya.facade.BillFacade;
import fi.codecrew.moya.model.Bill;
......@@ -204,8 +203,8 @@ public class CheckoutFiBean implements CheckoutFiBeanLocal {
}
final String returnUrl = new StringBuilder()
.append(BortalLocalContextHolder.isSsl() ? "https://" : "http://")
.append(BortalLocalContextHolder.getHostname())
.append("https://")
.append(eventbean.getCurrentHostname())
.append("/MoyaWeb/checkout/")
.toString();
......
......@@ -18,24 +18,23 @@
*/
package fi.codecrew.moya.beans;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.EJBAccessException;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.enums.apps.EventPermission;
import fi.codecrew.moya.enums.apps.SpecialPermission;
import fi.codecrew.moya.facade.EventFacade;
......@@ -67,6 +66,10 @@ public class EventBean implements EventBeanLocal {
private static final String DEFAULT_ORGANISATION_NAME = "Default organisation";
private static final Logger logger = LoggerFactory.getLogger(EventBean.class);
private static final String DEFAULT_EVENT_DOMAIN = null;
@Resource
private SessionContext context;
@EJB
private EventFacade eventFacade;
......@@ -88,18 +91,8 @@ public class EventBean implements EventBeanLocal {
@EJB
private LoggingBeanLocal logbean;
@Override
public LanEvent getEventByHostname(String hostname) {
LanEvent ret = eventFacade.findByHostname(hostname);
if (ret == null) {
ret = findOrCreateDefaultEvent();
}
return ret;
}
public LanEvent findOrCreateDefaultEvent() {
LanEvent ret = eventFacade.findByName(DEFAULT_EVENT_NAME);
LanEvent ret = eventFacade.find(1);
if (ret == null) {
logger.info("Default Event does not exist! creating new.");
ret = new LanEvent();
......@@ -125,19 +118,28 @@ public class EventBean implements EventBeanLocal {
return settings;
}
public String getCurrentHostname() {
Principal principal = context.getCallerPrincipal();
String hostname = null;
if (principal != null) {
hostname = UserLoginUtils.getDomainFromJaas(principal);
}
return hostname;
}
@Override
public LanEvent getCurrentEvent() {
String hostname = BortalLocalContextHolder.getHostname();
// logger.info("Current hostname from context: {}", hostname);
LanEvent ret = null;
if (BortalLocalContextHolder.getHostnameId() != null) {
ret = eventFacade.find(BortalLocalContextHolder.getHostnameId());
if (ret != null) {
String hostname = getCurrentHostname();
ret = getEventForHostname(hostname);
return ret;
}
}
public LanEvent getEventForHostname(String hostname) {
// logger.info("Current hostname from context: {}", hostname);
LanEvent ret = null;
if (hostname == null || hostname.isEmpty()) {
hostname = DEFAULT_EVENT_DOMAIN;
......@@ -152,9 +154,7 @@ public class EventBean implements EventBeanLocal {
ret = this.findOrCreateDefaultEvent();
}
BortalLocalContextHolder.setHostnameId(ret.getId());
return ret;
}
@Override
......
......@@ -29,6 +29,7 @@ import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -47,6 +48,7 @@ import fi.codecrew.moya.model.ApplicationPermission;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.Role;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
/**
* Session Bean implementation class SessionHandlerBean
......@@ -59,9 +61,9 @@ public class JaasBean implements MoyaRealmBeanRemote, JaasBeanLocal {
@EJB
private UserBean userbean;
@EJB
private PermissionBeanLocal permbean;
private PermissionBean permbean;
@EJB
private EventBeanLocal eventbean;
private EventBean eventbean;
@EJB
private RestBean restbean;
......@@ -102,11 +104,11 @@ public class JaasBean implements MoyaRealmBeanRemote, JaasBeanLocal {
private List<AuthenticationFormat> authFormats;
@Override
public AuthenticationResult authUsername(String username, String password) {
public AuthenticationResult authUsername(String jaasUsername, String password) {
AuthenticationResult ret = null;
for (AuthenticationFormat auth : authFormats) {
ret = auth.authenticate(username, password);
ret = auth.authenticate(jaasUsername, password);
if (ret != null) {
break;
}
......@@ -116,21 +118,16 @@ public class JaasBean implements MoyaRealmBeanRemote, JaasBeanLocal {
}
@Override
public boolean authenticate(String username, String password) {
return (normalAuthBean.tryLogin(username, password) != null);
}
public Enumeration<String> getGroupNames(String jaasUsername, String usertype) {
String user = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
LanEvent event = eventbean.getEventForHostname(UserLoginUtils.getDomainFromJaasString(jaasUsername));
@Override
public Enumeration<String> getGroupNames(String user, String usertype) {
EventUser usr = eventUserFacade.findByLogin(user.toLowerCase().trim());
HashSet<String> roleset = new HashSet<String>();
EventUser usr = eventUserFacade.findByLogin(user.toLowerCase().trim(), event);
HashSet<String> roleset = new HashSet<>();
roleset.add(UserPermission.ANYUSER.getFullName());
if (usr == null) {
usr = permbean.getAnonEventUser();
usr = permbean.getAnonEventUser(event);
roleset.add(SpecialPermission.ANONYMOUS.name());
}
......@@ -172,7 +169,6 @@ public class JaasBean implements MoyaRealmBeanRemote, JaasBeanLocal {
roleset.add(apperm.getPermission().getFullName());
}
}
LanEvent event = eventbean.getCurrentEvent();
if (event != null && !usr.getUser().isAnonymous() && event.getDefaultRole() != null) {
for (ApplicationPermission apperm : event.getDefaultRole().getPermissions()) {
......
......@@ -29,6 +29,9 @@ import javax.ejb.Stateless;
import javax.resource.spi.IllegalStateException;
import fi.codecrew.moya.enums.apps.*;
import fi.codecrew.moya.facade.EventFacade;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -126,7 +129,8 @@ public class PermissionBean implements PermissionBeanLocal {
private EventUserFacade eventUserFacade;
@EJB
private EventBeanLocal eventbean;
private EventBean eventbean;
@Override
public boolean hasPermission(SpecialPermission perm) {
......@@ -143,7 +147,6 @@ public class PermissionBean implements PermissionBeanLocal {
return false;
}
return context.isCallerInRole(perm.getFullName());
}
@Override
......@@ -154,10 +157,10 @@ public class PermissionBean implements PermissionBeanLocal {
@Override
public boolean isCurrentUser(String login) {
return (context.getCallerPrincipal() == null || login == null) ? false : context.getCallerPrincipal().getName().equals(login);
return login != null && login.equals(getPrincipalName());
}
@Override
public boolean isCurrentUser(EventUser user) {
return user != null && isCurrentUser(user.getUser());
......@@ -165,40 +168,31 @@ public class PermissionBean implements PermissionBeanLocal {
@Override
public boolean isLoggedIn() {
Principal principal = context.getCallerPrincipal();
boolean ret = principal != null && !User.ANONYMOUS_LOGINNAME.equalsIgnoreCase(principal.getName());
// logger.info("Checking principal {} against anon: {}", principal,
// ret);
return ret;
return !User.ANONYMOUS_LOGINNAME.equalsIgnoreCase(getPrincipalName());
}
@Override
public EventUser getCurrentUser() {
Principal principal = context.getCallerPrincipal();
EventUser ret = eventUserFacade.findByLogin(principal.getName());
LanEvent event = eventbean.getEventForHostname(getPrincipalDomain());
EventUser ret = eventUserFacade.findByLogin(getPrincipalName(), event);
if (ret == null) {
ret = getAnonEventUser();
}
return ret;
}
/**
* Makes sure default user and public role exist and the user is member of
* the role.
*/
@Override
public EventUser getAnonEventUser() {
EventUser defaultUser = eventUserFacade.findByLogin(User.ANONYMOUS_LOGINNAME);
public EventUser getAnonEventUser(LanEvent event) {
EventUser defaultUser = eventUserFacade.findByLogin(User.ANONYMOUS_LOGINNAME, event);
if (defaultUser == null) {
User user = userfacade.findByLogin(User.ANONYMOUS_LOGINNAME);
if (user == null) {
defaultUser = new EventUser(new User(), eventbean.getCurrentEvent(), null);
defaultUser = new EventUser(new User(), event, null);
defaultUser.getUser().setLogin(User.ANONYMOUS_LOGINNAME);
defaultUser.getUser().setNick(User.ANONYMOUS_LOGINNAME);
} else {
defaultUser = new EventUser(user, eventbean.getCurrentEvent(), null);
defaultUser = new EventUser(user, event, null);
}
eventUserFacade.create(defaultUser);
eventUserFacade.flush();
......@@ -207,21 +201,39 @@ public class PermissionBean implements PermissionBeanLocal {
return defaultUser;
}
public String getPrincipal() {
/**
* Makes sure default user and public role exist and the user is member of
* the role.
*/
@Override
public EventUser getAnonEventUser() {
return getAnonEventUser(eventbean.getCurrentEvent());
}
public String getPrincipalName() {
Principal principal = context.getCallerPrincipal();
//logger.debug("Principal: {}", principal);
String principalName = null;
if (principal != null) {
principalName = UserLoginUtils.geUsernameFromJaas(principal);
}
return principalName;
}
String principalName = principal.getName();
// logger.debug("Principal is {}", principalName);
public String getPrincipalDomain() {
return principalName;
Principal principal = context.getCallerPrincipal();
String principalDomain = null;
if (principal != null) {
principalDomain = UserLoginUtils.getDomainFromJaas(principal);
}
return principalDomain;
}
@Override
public String getCommonName() throws IllegalStateException {
String dn = context.getCallerPrincipal().getName();
String dn = getPrincipalName();
String[] parts = dn.split(",");
for (String part : parts) {
......
......@@ -18,6 +18,7 @@
*/
package fi.codecrew.moya.beans;
import java.security.Principal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
......@@ -35,6 +36,7 @@ import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -96,8 +98,9 @@ public class RestBean implements RestBeanLocal {
private ConcurrentHashMap<String, ConcurrentHashMap<String, Long>> userRestAuths = new ConcurrentHashMap<>();
@Override
public String getLoggedinUserRestNonce() {
String username = context.getCallerPrincipal().getName();
public String getLoggedinUserRestNonce()
{
String username = getPrincipalName();
if (username == null) {
return null;
}
......@@ -118,9 +121,10 @@ public class RestBean implements RestBeanLocal {
return nonce;
}
@Override
public boolean validateUserNonce(String nonce) {
String username = context.getCallerPrincipal().getName();
String username = getPrincipalName();
boolean ret = false;
// Validation is successfull if user exists, nonce exists and timeout has not passed.
......@@ -131,4 +135,14 @@ public class RestBean implements RestBeanLocal {
return ret;
}
public String getPrincipalName() {
Principal principal = context.getCallerPrincipal();
String principalName = null;
if (principal != null) {
principalName = UserLoginUtils.geUsernameFromJaas(principal);
}
return principalName;
}
}
......@@ -52,6 +52,7 @@ import fi.codecrew.moya.enums.apps.UserPermission;
public class SessionMgmtBean implements SessionMgmtBeanLocal {
private final ConcurrentHashMap<String, UserContainer> sessionUsers = new ConcurrentHashMap<>();
private final Set<HttpSession> sessions = Collections.newSetFromMap(new ConcurrentHashMap<HttpSession, Boolean>());
@SuppressWarnings("unused")
......@@ -67,12 +68,13 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal {
public void updateSessionUser(String sessionId, String user) {
if (!sessionUsers.containsKey(sessionId)) {
sessionUsers.putIfAbsent(sessionId, new UserContainer(BortalLocalContextHolder.getHostname(), user));
sessionUsers.putIfAbsent(sessionId, new UserContainer(user));
}
}
@Override
public void sessionCreated(HttpSession session) {
sessions.add(session);
}
......
......@@ -226,7 +226,7 @@ public class UserBean implements UserBeanLocal {
// currentEventuser, currentEventuserRoles);
// return currentEventuserRoles;
// }
LanEvent event = eventBean.getCurrentEvent();
LanEvent event = u.getEvent();
Set<Role> checkedRoles = new HashSet<Role>();
......
......@@ -57,7 +57,6 @@ import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import fi.codecrew.moya.beanutil.DecimalXMLAdapter;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.enums.apps.BillPermission;
import fi.codecrew.moya.facade.BillFacade;
import fi.codecrew.moya.facade.LanEventPrivatePropertyFacade;
......@@ -169,7 +168,8 @@ public class VerkkomaksutFiBean implements VerkkomaksutFiBeanLocal {
{
return null;
}
String returnUrl = new StringBuilder("http://").append(BortalLocalContextHolder.getHostname())
String returnUrl = new StringBuilder("https://")
.append(eventbean.getCurrentHostname())
.append("/MoyaWeb/svm/").toString();
PaymentEntry message = new PaymentEntry(returnUrl);
......
......@@ -2,6 +2,7 @@ package fi.codecrew.moya.beans.auth;
import javax.ejb.EJB;
import fi.codecrew.moya.model.LanEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -19,19 +20,19 @@ public class ApiAuth {
private static final Logger logger = LoggerFactory.getLogger(ApiAuth.class);
protected ApiApplicationInstance verifyAppInstance(String appId, String userId) {
protected ApiApplicationInstance verifyAppInstance(String appId, String userId, LanEvent event) {
ApiApplication app = appfacade.findByAppid(appId);
if (app == null) {
logger.warn("Rest auth failed: Application not found for appid {}", appId);
return null;
}
ApiApplicationInstance apiInstance = appInstanceFacade.findInstance(app, userId);
ApiApplicationInstance apiInstance = appInstanceFacade.findInstance(app, userId, event);
if (apiInstance == null) {
logger.warn("Rest auth failed; because appInstance not found for app{} and user {}", app, userId);
return null;
}
if (!app.isEnabled() || !apiInstance.isEnabled()) {
logger.warn("Rest auth failed: app or api-instance is disabled: app {}, apiInstance: {}", app, apiInstance);
logger.warn("Rest auth failed: app or api-instance is disabled: app {}, apiInstance: {}", app, apiInstance);
return null;
}
return apiInstance;
......
......@@ -7,6 +7,9 @@ import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import fi.codecrew.moya.beans.EventBean;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -30,10 +33,16 @@ public class BasicAuthPBean extends ApiAuth implements AuthenticationFormat {
private ApiApplicationFacade appfacade;
@EJB
private ApiApplicationInstanceFacade appInstanceFacade;
@EJB
private EventBean eventbean;
@Override
public AuthenticationResult authenticate(String username, String password) {
public AuthenticationResult authenticate(String jaasUsername, String password) {
AuthenticationResult ret = null;
String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
String domain = UserLoginUtils.getDomainFromJaasString(jaasUsername);
LanEvent event = eventbean.getEventForHostname(domain);
if ((username == null || username.isEmpty()) && password.startsWith(HEADER_PREFIX)) {
ret = new AuthenticationResult();
ret.setUsertype(UserType.REST.name());
......@@ -57,9 +66,9 @@ public class BasicAuthPBean extends ApiAuth implements AuthenticationFormat {
final String userId = splitStr[2];
final String appKey = splitStr[3];
ApiApplicationInstance appInstance = verifyAppInstance(appId, userId);
ApiApplicationInstance appInstance = verifyAppInstance(appId, userId, event);
if (appInstance != null && appKey != null && !appKey.isEmpty() && appKey.equals(appInstance.getSecretKey())) {
ret.setUsername(getUsername(appInstance));
ret.setUsername(getUsername(appInstance) + '@' + domain);
}
} catch (Exception e) {
logger.warn("Invalid base64 string on Rest Basic auth: " + password, e);
......
......@@ -4,6 +4,9 @@ import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import fi.codecrew.moya.beans.EventBean;
import fi.codecrew.moya.facade.LanEventPropertyFacade;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -34,25 +37,29 @@ public class NormalAuthPBean implements AuthenticationFormat {
private UserFacade userfacade;
@EJB
private EventBeanLocal eventbean;
private EventBean eventbean;
@EJB
private LanEventPropertyFacade eventPropertyFacade;
@Override
public AuthenticationResult authenticate(String username, String password) {
public AuthenticationResult authenticate(String jaasUsername, String password) {
String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
String domain = UserLoginUtils.getDomainFromJaasString(jaasUsername);
LanEvent event = eventbean.getEventForHostname(domain);
AuthenticationResult ret = null;
EventUser retUser = tryLogin(username, password);
EventUser retUser = tryLogin(username, password, event);
if (retUser != null) {
ret = new AuthenticationResult();
ret.setUsertype(UserType.USER.name());
ret.setUsername(retUser.getLogin());
ret.setUsername(retUser.getLogin() + '@' + domain);
}
return ret;
}
public EventUser tryLogin(String username, String password) {
private EventUser tryLogin(String username, String password, LanEvent event) {
// username = username.trim().toLowerCase();
EventUser eventUser = eventUserFacade.findByLogin(username);
EventUser eventUser = eventUserFacade.findByLogin(username, event);
// logger.info("Found eventuser '{}' with username '{}'", eventUser,
// username);
......@@ -64,28 +71,24 @@ public class NormalAuthPBean implements AuthenticationFormat {
user = eventUser.getUser();
}
logger.info("User '{}' with '{}' ", user, username);
// If there is no eventuser found, try to create one.
if (user != null) {
logger.info("TryLogin user not null: {}, login {}", user, user.getLogin());
if (user.isAnonymous()) {
logger.info("logging in as anonymous!!!");
} else if (!user.checkPassword(password)) {
secubean.sendMessage(MoyaEventType.LOGIN_FAILED, eventUser,
"Login failed: wrong password for username: ", username);
secubean.sendMessage(MoyaEventType.LOGIN_FAILED, eventUser, "Login failed: wrong password for username: ", username);
eventUser = null;
user = null;
}
LanEventProperty inviteonly = eventbean.getProperty(LanEventPropertyKey.INVITE_ONLY_EVENT);
LanEventProperty inviteonly = eventPropertyFacade.find(event, LanEventPropertyKey.INVITE_ONLY_EVENT);
boolean createEventuser = true;
if (inviteonly != null && inviteonly.isBooleanValue()) {
createEventuser = false;
}
if (createEventuser && user != null && eventUser == null) {
LanEvent event = eventbean.getCurrentEvent();
eventUser = new EventUser(user, event, null);
// eventUser.setCreator(eventUser);
eventUserFacade.create(eventUser);
......@@ -96,11 +99,9 @@ public class NormalAuthPBean implements AuthenticationFormat {
// jos logitetaan anomuumi, niin uuden tapahtuman luominen hajoaa
// jännästi.
if (user != null && !user.isAnonymous())
secubean.sendMessage(MoyaEventType.LOGIN_SUCCESSFULL, eventUser, "User logged in with username: '",
username, "' eventuser: ", eventUser);
secubean.sendMessage(MoyaEventType.LOGIN_SUCCESSFULL, eventUser, "User logged in with username: '", username, "' eventuser: ", eventUser);
} else {
secubean.sendMessage(MoyaEventType.LOGIN_FAILED, eventUserFacade.findByLogin(User.ANONYMOUS_LOGINNAME),
"Login failed: Username not found: ", username);
secubean.sendMessage(MoyaEventType.LOGIN_FAILED, eventUserFacade.findByLogin(User.ANONYMOUS_LOGINNAME, event), "Login failed: Username not found: ", username);
}
return eventUser;
......
package fi.codecrew.moya.beans.auth;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import fi.codecrew.moya.beans.EventBean;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -18,50 +22,54 @@ public class RestMacAuthPBean extends ApiAuth implements AuthenticationFormat {
private static final Logger logger = LoggerFactory.getLogger(RestMacAuthPBean.class);
@EJB
private EventBean eventbean;
@Override
public AuthenticationResult authenticate(String username, String password) {
public AuthenticationResult authenticate(String jaasUsername, String password) {
String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
String domain = UserLoginUtils.getDomainFromJaasString(jaasUsername);
LanEvent event = eventbean.getEventForHostname(domain);
AuthenticationResult ret = null;
if ((username == null || username.isEmpty()) && password.startsWith(JaasBeanLocal.REST_PREFIX)) {
ret = new AuthenticationResult();
ret.setUsertype(UserType.REST.name());
ret.setUsername(restAuth(password));
ret.setUsername(restAuth(password, event) + '@'+domain);
}
return ret;
}
private String restAuth(String restauth) {
private String restAuth(String restauth, LanEvent event) {
String[] authsplit = restauth.split(":", 6);
logger.info("Trying to auth with rest {}", (Object) authsplit);
if (authsplit.length != 6 || !authsplit[0].equals("rest")) {
return null;
}
return authenticateApp(authsplit[5], authsplit[1], authsplit[2], authsplit[3], authsplit[4]);
return authenticateApp(authsplit[5], authsplit[1], authsplit[2], authsplit[3], authsplit[4], event);
}
public String authenticateApp(String pathInfo, String appId, String userId, String appStamp, String mac) {
public String authenticateApp(String pathInfo, String appId, String userId, String appStamp, String mac, LanEvent event) {
logger.info("Authenticat app with pathinfo {}, appid {}, userid {}, appstamp {}, mac {}",
new Object[] { pathInfo, appId, userId, appStamp, mac });
logger.info("Authenticat app with pathinfo {}, appid {}, userid {}, appstamp {}, mac {}", new Object[]{pathInfo, appId, userId, appStamp, mac});
if (mac == null) {
logger.warn("Rest auth failed: Mac is null");
return null;
}
ApiApplicationInstance apiInstance = verifyAppInstance(appId, userId);
if (apiInstance == null)
ApiApplicationInstance apiInstance = verifyAppInstance(appId, userId, event);
if (apiInstance == null) {
return null;
}
String ret = null;
String macSource = PasswordFunctions.mkSeparatedString("+", pathInfo, appId, userId, appStamp,
apiInstance.getSecretKey());
String macSource = PasswordFunctions.mkSeparatedString("+", pathInfo, appId, userId, appStamp, apiInstance.getSecretKey());
String macHash = PasswordFunctions.calculateSha1(macSource);
logger.info("Calculated hash {}, comparing to {}", macHash, mac);
if (mac.equalsIgnoreCase(macHash)) {
ret = getUsername(apiInstance);
} else {
logger.warn("Rest auth failed: Calculated hash does not match received mac: Calculated {}, received {}",
macHash, mac);
logger.warn("Rest auth failed: Calculated hash does not match received mac: Calculated {}, received {}", macHash, mac);
}
return ret;
......
......@@ -13,6 +13,7 @@ import javax.jms.JMSDestinationDefinition;
import javax.jms.ObjectMessage;
import javax.jms.Topic;
import fi.codecrew.moya.model.LanEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -63,12 +64,18 @@ public class MoyaEventSender implements LoggingBeanLocal {
MoyaEventMessage msg = new MoyaEventMessage();
msg.setEventtype(type);
msg.setTime(Calendar.getInstance());
if(user != null)
{
if (user != null) {
msg.setEventUserId(user.getId());
msg.setEventId(user.getEvent().getId());
}
EventUser currusr = permbean.getCurrentUser();
if (currusr != null) {
msg.setCurrentUserId(currusr.getUser().getId());
}
LanEvent currevent = eventbean.getCurrentEvent();
if (currevent != null) {
msg.setEventId(currevent.getId());
}
msg.setCurrentUserId(permbean.getCurrentUser().getUser().getId());
msg.setEventId(eventbean.getCurrentEvent().getId());
msg.setDescription(message);
logger.debug("Sending Moya message {} with description ", type, message);
sendMessage(msg);
......
......@@ -24,9 +24,7 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import fi.codecrew.moya.model.ApiApplication;
import fi.codecrew.moya.model.ApiApplicationInstance;
import fi.codecrew.moya.model.ApiApplicationInstance_;
import fi.codecrew.moya.model.*;
@Stateless
@LocalBean
......@@ -37,12 +35,13 @@ public class ApiApplicationInstanceFacade extends IntegerPkGenericFacade<ApiAppl
}
public ApiApplicationInstance findInstance(ApiApplication app, String userId) {
public ApiApplicationInstance findInstance(ApiApplication app, String userId, LanEvent event) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<ApiApplicationInstance> q = cb.createQuery(ApiApplicationInstance.class);
Root<ApiApplicationInstance> root = q.from(ApiApplicationInstance.class);
q.where(cb.equal(root.get(ApiApplicationInstance_.application), app),
cb.equal(root.get(ApiApplicationInstance_.authname), userId));
cb.equal(root.get(ApiApplicationInstance_.authname), userId),
cb.equal(root.get(ApiApplicationInstance_.eventuser).get(EventUser_.event), event));
return super.getSingleNullableResult(getEm().createQuery(q));
}
......
......@@ -41,28 +41,6 @@ public class EventFacade extends IntegerPkGenericFacade<LanEvent> {
super(LanEvent.class);
}
public LanEvent findByHostname(String hostname) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<LanEvent> cq = cb.createQuery(LanEvent.class);
Root<LanEvent> root = cq.from(LanEvent.class);
cq.where(cb.equal(root.get(LanEvent_.eventEnabled), true));
// TypedQuery<LanEvent> q =
// em.createNamedQuery("LanEvent.findByReferer", LanEvent.class);
// q.setParameter("referer", hostname);
return getSingleNullableResult(getEm().createQuery(cq));
}
public LanEvent findByName(String name) {
// TypedQuery<LanEvent> q = em.createNamedQuery("LanEvent.findByName",
// LanEvent.class);
// q.setParameter("name", name);
// return getSingleNullableResult(q);
return this.find(1);
}
public String flushCache() {
getEm().getEntityManagerFactory().getCache().evictAll();
return "Evicted all!";
......
......@@ -76,6 +76,10 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> {
public EventUser findByLogin(final String login) {
LanEvent event = eventBean.getCurrentEvent();
return findByLogin(login, event);
}
public EventUser findByLogin(final String login, final LanEvent event) {
EventUser ret;
if ((ret = checkCache(login, event)) == null)
{
......
......@@ -39,15 +39,12 @@ public class LanEventPropertyFacade extends IntegerPkGenericFacade<LanEventPrope
super(LanEventProperty.class);
}
@EJB
private EventBeanLocal eventbean;
public LanEventProperty find(LanEvent currentEvent, LanEventPropertyKey property) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<LanEventProperty> cq = cb.createQuery(LanEventProperty.class);
Root<LanEventProperty> root = cq.from(LanEventProperty.class);
CriteriaQuery<LanEventProperty> q = cq.where(cb.equal(root.get(LanEventProperty_.event), eventbean.getCurrentEvent()),
CriteriaQuery<LanEventProperty> q = cq.where(cb.equal(root.get(LanEventProperty_.event), currentEvent),
cb.equal(root.get(LanEventProperty_.key), property)
);
return getSingleNullableResult(getEm().createQuery(q));
......
......@@ -113,7 +113,7 @@ public class OrgRoleFacade extends IntegerPkGenericFacade<OrgRole> {
}
public List<Role> findRolesForUser(EventUser u) {
LanEvent event = eventBean.getCurrentEvent();
LanEvent event = u.getEvent();
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Role> cq = cb.createQuery(Role.class);
......
......@@ -57,7 +57,7 @@ public class RoleFacade extends IntegerPkGenericFacade<Role> {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Role> cq = cb.createQuery(Role.class);
Root<Role> root = cq.from(Role.class);
cq.where(cb.equal(root.get(Role_.event), eventbean.getCurrentEvent()), cb.isMember(user, root.get(Role_.users)));
cq.where(cb.equal(root.get(Role_.event), user.getEvent()), cb.isMember(user, root.get(Role_.users)));
return getEm().createQuery(cq).getResultList();
}
......
package fi.codecrew.moya.utilities;
import java.security.Principal;
public class UserLoginUtils {
public static String getDomainFromJaas(Principal principal) {
if (principal == null) {
return null;
}
String principalName = principal.getName();
return getDomainFromJaasString(principalName);
}
public static String getDomainFromJaasString(String principalName) {
if (principalName == null || principalName.equals("ANONYMOUS")) {
return null;
}
String[] ret = principalName.split("@");
if (ret.length < 2) {
throw new IndexOutOfBoundsException("Can not get domain name from principal " + principalName);
}
return ret[ret.length - 1];
}
public static String geUsernameFromJaas(Principal principal) {
if (principal == null) {
return null;
}
return getUsernameFromJaasString(principal.getName());
}
public static String getUsernameFromJaasString(String username) {
return username.split("@[^@]+$")[0];
}
}
......@@ -21,7 +21,6 @@ package fi.codecrew.moya;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.Principal;
import java.util.Enumeration;
import javax.ejb.EJB;
import javax.faces.application.ProjectStage;
......@@ -37,6 +36,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
......@@ -166,9 +166,8 @@ public class HostnameFilter implements Filter {
httpRequest = (HttpServletRequest) request;
insertServerLoggingContext(httpRequest, authtype);
parseHostname(httpRequest);
Principal principal = httpRequest.getUserPrincipal();
if (principal == null) {
String hostname = parseHostname(httpRequest);
if (httpRequest.getUserPrincipal() == null) {
// Check if we are logging in with rest
if (RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())) {
authtype = AuthType.REST;
......@@ -187,14 +186,12 @@ public class HostnameFilter implements Filter {
} else {
try {
authtype = AuthType.ANON;
httpRequest.login(User.ANONYMOUS_LOGINNAME, null);
httpRequest.login(User.ANONYMOUS_LOGINNAME + '@' + hostname, null);
} catch (Exception t) {
logger.warn("Error logging in as anonymous... ignoring.. ", t);
}
}
} else if (principal.getName() == null) {
logger.warn("Principal has a null name", principal.toString());
} else if (!principal.getName().equals(User.ANONYMOUS_LOGINNAME)) {
} else if (!httpRequest.getUserPrincipal().getName().equals(User.ANONYMOUS_LOGINNAME + '@' + hostname)) {
authtype = AuthType.USER;
sessionmgmt.updateSessionUser(httpRequest.getSession().getId(), httpRequest.getUserPrincipal().getName());
}
......@@ -202,7 +199,6 @@ public class HostnameFilter implements Filter {
// Update logging context
insertUserLoggingContext(httpRequest, authtype);
// pass the request along the filter chain
chain.doFilter(request, response);
} catch (Exception t) {
......@@ -257,7 +253,7 @@ public class HostnameFilter implements Filter {
}
boolean ret = true;
try {
httpRequest.login(null, restAuthStr);
httpRequest.login('@' + parseHostname(httpRequest), restAuthStr);
} catch (ServletException loginEx) {
ret = false;
logger.info("Rest api authentication failed for path " + httpRequest.getPathInfo() + " "
......@@ -271,71 +267,34 @@ public class HostnameFilter implements Filter {
return ret;
}
protected void parseHostname(HttpServletRequest httpRequest) {
protected String parseHostname(HttpServletRequest httpRequest) {
StringBuffer url = httpRequest.getRequestURL();
String requestHostHeader = httpRequest.getHeader("host");
String headerHostname = null;
String hostname = "localhost";
if (requestHostHeader != null) {
headerHostname = requestHostHeader.split(":")[0];
}
int beginindex = url.indexOf("//", 0);
if (beginindex < 0) {
beginindex = 0;
} else {
beginindex = beginindex + 2;
}
// Find the first / from URL after http://
int slashindex = url.indexOf("/", beginindex);
int colonindex = url.indexOf(":", beginindex);
int lastindex = slashindex;
if (colonindex >= 0 && slashindex > colonindex) {
lastindex = colonindex;
}
if (lastindex < 0) {
lastindex = url.length() - 1;
hostname = requestHostHeader.split(":")[0];
}
String hostname = url.substring(beginindex, lastindex);
// if proxy provides scheme in header, use it..
String scheme = httpRequest.getHeader(X_FORWARDED_PROTO);
if (scheme == null || scheme.isEmpty()) {
scheme = url.substring(0, 5).toLowerCase();
}
boolean ssl = scheme.trim().toLowerCase().equals("https");
BortalLocalContextHolder.setSsl(ssl);
HttpSession session = httpRequest.getSession();
Object sessionHostname = session.getAttribute(SESSION_HOSTNAMESTORE);
if (sessionHostname == null) {
session.setAttribute(SESSION_HOSTNAMESTORE, hostname);
} else if (!hostname.equals(sessionHostname)) {
Principal principal = httpRequest.getUserPrincipal();
String login = null;
if (principal != null) {
login = principal.getName();
}
logbean.sendMessage(MoyaEventType.USER_PERMISSION_VIOLATION,
"Hostname mismatch privilege escalation! User '", login, "' tried to change hostname from '",
sessionHostname, "' to '", hostname, ",");
String userDomain = UserLoginUtils.getDomainFromJaas(httpRequest.getUserPrincipal());
if (!hostname.equals(userDomain)) {
logbean.sendMessage(MoyaEventType.USER_PERMISSION_VIOLATION,
"Hostname mismatch privilege escalation! User '", httpRequest.getUserPrincipal(), "' tried to change hostname from '",
userDomain, "' to '", hostname, ",");
throw new RuntimeException("Hostname mismatch!");
}
if (headerHostname != null) {
if (!headerHostname.equals(hostname)) {
logger.warn("Host header and parsed hostname do not match! Header: {}, Parsed: {}", headerHostname, hostname);
}
} else {
logger.warn("Header Host is null for url {}", hostname);
}
BortalLocalContextHolder.setHostname(hostname);
BortalLocalContextHolder.setInDevelopmentMode(developmentMode);
return hostname;
}
}
......@@ -40,7 +40,7 @@ public class Hello implements ICommandlineCommand {
return 1;
} else {
String currentUser = permBean.getPrincipal();
String currentUser = permBean.getPrincipalName();
if (currentUser.equals(argv[1])) {
stdout.write("hello, " + argv[1] + "\r\n");
} else {
......
......@@ -220,9 +220,13 @@ public class UserRestView {
}
}
if (principal == null || principal.getName() == null || !principal.getName().equals(username)) {
String requestHostHeader = servletRequest.getHeader("host");
String hostname = null;
if (requestHostHeader != null) {
hostname = requestHostHeader.split(":")[0];
}
servletRequest.getSession(true);
servletRequest.login(username, password);
servletRequest.login(username + '@' + hostname, password);
}
} catch (ServletException e) {
success = false;
......
......@@ -38,6 +38,8 @@ import org.slf4j.LoggerFactory;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
// Deprecated: TODO: Pitäisi käydä ajatuksella läpi!
@Deprecated()
public class BortalPasswordAuthenticator implements PasswordAuthenticator {
private static final Logger logger = LoggerFactory.getLogger(BortalPasswordAuthenticator.class);
......
......@@ -142,6 +142,11 @@ public class AuthView extends GenericCDIView {
}
HttpServletRequest request = getRequest();
String requestHostHeader = request.getHeader("host");
String hostname = null;
if (requestHostHeader != null) {
hostname = requestHostHeader.split(":")[0];
}
if (request.getUserPrincipal() != null) {
logger.info("Principal not empty. need to logout first");
......@@ -159,7 +164,7 @@ public class AuthView extends GenericCDIView {
login = userlogin;
}
try {
request.login(login.trim().toLowerCase(), password);
request.login(login.trim().toLowerCase()+'@'+hostname, password);
} catch (Exception e) {
this.loginError = true;
logger.info("Error while trying to login {}", e.getMessage());
......
......@@ -32,6 +32,7 @@ import javax.servlet.http.HttpSession;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal.UserContainer;
import fi.codecrew.moya.utilities.UserLoginUtils;
public class HttpSessionWrapper
{
......@@ -129,8 +130,8 @@ public class HttpSessionWrapper
String username = null;
String hostname = null;
if (uc != null) {
username = uc.getUsername();
hostname = uc.getHostname();
username = UserLoginUtils.getUsernameFromJaasString(uc.getUsername());
hostname = UserLoginUtils.getDomainFromJaasString(uc.getUsername());
}
ret.add(new HttpSessionWrapper(s, username, hostname));
}
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!