package de.bwlehrpool.bwlp_guac; import java.io.IOException; import java.util.*; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.form.TextField; import org.apache.guacamole.net.auth.*; import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException; import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.xml.soap.Text; import org.apache.guacamole.form.Field; import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException; import org.apache.guacamole.net.auth.credentials.CredentialsInfo; public class BwlpAuthenticationProvider implements AuthenticationProvider { Logger LOGGER = LoggerFactory.getLogger(BwlpAuthenticationProvider.class); public String getIdentifier() { return "de.bwlehrpool.bwgpul"; } public Object getResource() throws GuacamoleException { return null; } public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { // XXX We can somehow request additional fields to be shown during login by throwing an exception // that declares additional ones; but when I tried, it removed the existing username and password // field, so do we need to state them too? Seems wrong since we don't need them, we'd just want // an additional field to pick the room/location we want to end up in and let the actual // authentication plugin define the username/password fields. return null; } public AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser, Credentials credentials) throws GuacamoleException { return null; } public UserContext getUserContext(AuthenticatedUser authenticatedUser) throws GuacamoleException { LOGGER.warn("Ignoring getUserContext for " + authenticatedUser.toString()); return null; } public UserContext updateUserContext(UserContext context, AuthenticatedUser authenticatedUser, Credentials credentials) throws GuacamoleException { LOGGER.warn("Ignoring updateUserContext called with " + context.toString()); return null; } public UserContext decorate(UserContext context, AuthenticatedUser authenticatedUser, Credentials credentials) throws GuacamoleException { String username = authenticatedUser.getCredentials().getUsername(); LOGGER.warn("decorate called for " + username); BwlpUserContext user = oldMappings.get(username); if (user != null) return user; int locationid = requestLocation(credentials); LOGGER.warn("Doing the decoration"); user = new BwlpUserContext(authenticatedUser, context, locationid); oldMappings.put(username, user); return user; } private Map oldMappings = Collections .synchronizedMap(new WeakHashMap()); public UserContext redecorate(UserContext decorated, UserContext context, AuthenticatedUser authenticatedUser, Credentials credentials) throws GuacamoleException { String username = authenticatedUser.getCredentials().getUsername(); LOGGER.warn("REdecorate called for " + username); BwlpUserContext user = oldMappings.get(username); if (user != null && user.hasValidConnection()) return user; int locationid = requestLocation(credentials); LOGGER.warn("Doing the REdecoration"); user = new BwlpUserContext(authenticatedUser, context, locationid); oldMappings.put(username, user); return user; } private int requestLocation(Credentials credentials) throws GuacamoleException { // Request the user to select a location ConnectionManager.updateList(); HttpServletRequest request = credentials.getRequest(); String locationJson = request.getParameter("location"); if (locationJson == null) { throw new GuacamoleInsufficientCredentialsException( "Select Location", new CredentialsInfo( Collections.singletonList(new LocationField()) )); } ObjectMapper mapper = new ObjectMapper(); String message = "Select a Location"; int selectedId = 0; boolean tryAgain = false; String password = ""; String correctPassword = null; try { JsonNode location = mapper.readTree(locationJson); selectedId = Integer.parseInt(location.get("id").asText()); if (selectedId != 0) { password = location.get("password").asText(); correctPassword = ConnectionManager.getLocationPool().get(selectedId).password; } } catch (Exception e) { LOGGER.info("Error reading location"); LOGGER.info(e.toString()); tryAgain = true; } if (selectedId != 0 && correctPassword != null && !password.equals(correctPassword)) { tryAgain = true; message = "Wrong password!"; } if (tryAgain) { throw new GuacamoleCredentialsException( message, new CredentialsInfo( Collections.singletonList(new LocationField()) )); } return selectedId; } public void shutdown() { } }