Lots of restructuring, we'll need to dive deeper into this to make the import jobs actually work

This commit is contained in:
Robin Eklund 2011-08-03 17:50:25 +02:00
parent aa931305f6
commit bed74f671a
16 changed files with 201 additions and 408 deletions

@ -1,6 +1,5 @@
package se.su.dsv.scipro; package se.su.dsv.scipro;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -8,7 +7,6 @@ import java.util.List;
import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.wicket.Request; import org.apache.wicket.Request;
import org.apache.wicket.Session; import org.apache.wicket.Session;
@ -23,7 +21,7 @@ import se.su.dsv.scipro.data.dao.interfaces.UserSettingsDao;
import se.su.dsv.scipro.data.dataobjects.Project; import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.UserSettings; import se.su.dsv.scipro.data.dataobjects.UserSettings;
import se.su.dsv.scipro.json.IUserLookup; import se.su.dsv.scipro.json.IUserLookupFromUsername;
import se.su.dsv.scipro.security.auth.Authenticator; import se.su.dsv.scipro.security.auth.Authenticator;
import se.su.dsv.scipro.security.auth.roles.Admin; import se.su.dsv.scipro.security.auth.roles.Admin;
import se.su.dsv.scipro.security.auth.roles.DefaultRole; import se.su.dsv.scipro.security.auth.roles.DefaultRole;
@ -33,6 +31,7 @@ import se.su.dsv.scipro.security.auth.roles.IRole;
import se.su.dsv.scipro.security.auth.roles.Roles; import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.security.auth.roles.Student; import se.su.dsv.scipro.security.auth.roles.Student;
import se.su.dsv.scipro.security.auth.roles.SysAdmin; import se.su.dsv.scipro.security.auth.roles.SysAdmin;
import se.su.dsv.scipro.util.KeyValuePair;
public class SciProSession extends WebSession { public class SciProSession extends WebSession {
@ -49,8 +48,8 @@ public class SciProSession extends WebSession {
@SpringBean @SpringBean
private UserSettingsDao userSettingsDao; private UserSettingsDao userSettingsDao;
@SpringBean(name="userFullLookup") @SpringBean
private IUserLookup userLookup; private IUserLookupFromUsername userLookupFromUsername;
private List<IRole> iRoles = new ArrayList<IRole>(); private List<IRole> iRoles = new ArrayList<IRole>();
private User user = null; private User user = null;
@ -146,14 +145,10 @@ public class SciProSession extends WebSession {
//Query for the user //Query for the user
user = userDao.getUserByUsername(username,realm); user = userDao.getUserByUsername(username,realm);
if(user == null){ if(user == null){
try{ user = doUserLookup(username,realm);
user = doUserLookup(username); if(user == null){
if(user == null){ return false;
throw new NullPointerException("No user with username "+username+" found in the database or in daisy."); }
}
} catch (NullPointerException e) {
throw e;
}
} }
//Set mail-address session attributes //Set mail-address session attributes
setLoggedInIdentity(username+"@"+realm); setLoggedInIdentity(username+"@"+realm);
@ -269,23 +264,10 @@ public class SciProSession extends WebSession {
return true; return true;
return false; return false;
} }
private User doUserLookup(final String username, final String realm) {
private User doUserLookup(String username) throws NullPointerException { final User u = userLookupFromUsername.lookup(new KeyValuePair<String>(username,realm));
try{ if(u == null)
User u = userLookup.lookup(username); logger.warn(username + " authenticated successfully, but the user was not available from remote system.");
if(u != null){ return u;
return u;
}
Logger.getLogger("Application").log(Level.WARN, "" + username + " authenticated successfully, but the user was not found from daisy");
return null;
} catch (IOException ioe){
//TODO: Log exception
//ioe.printStackTrace();
throw new NullPointerException("Could not communicate with daisy");
} catch (Exception e) {
//TODO: Log exception
//e.printStackTrace();
throw new NullPointerException(e.getMessage());
}
} }
} }

@ -2,12 +2,8 @@ package se.su.dsv.scipro.data.dao.interfaces;
import java.util.List; import java.util.List;
import se.su.dsv.scipro.data.dataobjects.MessageBoard;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.Role; import se.su.dsv.scipro.data.dataobjects.Role;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.enums.ProjectStatus;
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
public interface UserDao extends LazyDeleteDao<User> { public interface UserDao extends LazyDeleteDao<User> {

@ -1,82 +0,0 @@
package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* This class does a lookup on a username against the remote remoteLookupUrl specified in
* the applicationContext, under ApplicationSettings.
*
* This class does NOT handle Daisys merging of users and is not maintained.
*
* @author Dan Kjellman <dan-kjel@dsv.su.se>
*/
@Deprecated
@Component("userFullLookup")
public class DefaultUserFullLookup implements IUserLookup {
/*
* References populated by spring
*/
@Autowired
private UserDao userDao;
@Autowired
private JsonUserFullResponseHandler userResponseHandler;
@Autowired
private ApplicationSettings settings;
private Logger logger;
public DefaultUserFullLookup(){
logger = Logger.getLogger(this.getClass());
}
/**
* Perform lookup against remote server
*
* @param username the username to lookup
* @throws IOException if there was an error in the connection
*/
public User lookup(String username) throws IOException {
if(username == null){
logger.log(Level.ERROR, "Trying to pass null instead of a username to the userlookup");
throw new IllegalStateException("You cannot pass null as the lookup parameter");
}
logger.log(Level.INFO,"Starting lookup for username: " + username);
Map<String, String> params = new HashMap<String, String>();
//For now you can only log in with dsv.su.se accounts...
params.put("username", username);
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{
request.processRequest();
} catch (IOException e) {
//Gets logged by the requestsender....
throw e;
}
/*
* Lookup the user and return
*/
User u = userDao.getUserByUsername(username);
if(u != null){
logger.log(Level.INFO, "Imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+username+") id: " + u.getId());
}
return u;
}
}

@ -1,80 +0,0 @@
package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* This class does a lookup on a username against the remote remoteLookupUrl specified in
* the applicationContext, under ApplicationSettings.
*
* This class does NOT handle Daisys merging of users and is not maintained.
*
* @author Dan Kjellman <dan-kjel@dsv.su.se>
*/
@Component("userLookup")
public class DefaultUserLookup implements IUserLookup {
/*
* References populated by spring
*/
@Autowired
private UserDao userDao;
@Autowired
private JsonUserResponseHandler userResponseHandler;
@Autowired
private ApplicationSettings settings;
private Logger logger;
public DefaultUserLookup(){
logger = Logger.getLogger(this.getClass());
}
/**
* Perform lookup against remote server
*
* @param username the username to lookup
* @throws IOException if there was an error in the connection
*/
public User lookup(String username) throws IOException {
if(username == null){
logger.log(Level.ERROR, "Trying to pass null instead of a username to the userlookup");
throw new IllegalStateException("You cannot pass null as the lookup parameter");
}
logger.log(Level.INFO,"Starting lookup for userid: " + username);
Map<String, String> params = new HashMap<String, String>();
//For now you can only log in with dsv.su.se accounts...
params.put("userid", username);
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{
request.processRequest();
} catch (IOException e) {
//Gets logged by the requestsender....
throw e;
}
/*
* Lookup the user and return
*/
User u = userDao.getUserByUsername(username);
if(u != null){
logger.log(Level.INFO, "Imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+username+") id: " + u.getId());
}
return u;
}
}

@ -0,0 +1,32 @@
package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
/**
* Package-private Abstract base for the public UserLookups.
*/
abstract class DefaultUserLookupBase{
@Autowired
protected UserDao userDao;
@Autowired
protected JsonUserResponseHandler userResponseHandler;
@Autowired
protected ApplicationSettings settings;
protected boolean doRemoteRequest(final Map<String,String> params){
userResponseHandler.setLogResult(true);
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{
request.processRequest();
} catch (final IOException e){
return false;
}
return true;
}
}

@ -0,0 +1,34 @@
package se.su.dsv.scipro.json;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* Default implementation of IUserLookupFromIdentifier queries remote defined by ApplicationSettings via JSon requests.
*/
@Component("userLookupFromIdentifier")
public class DefaultUserLookupFromIdentifier extends DefaultUserLookupBase implements IUserLookupFromIdentifier {
private Logger logger = Logger.getLogger(DefaultUserLookupFromIdentifier.class);
public User lookup(final Long identifier){
if(identifier == null){
throw new IllegalStateException("null values for user parameter not allowed");
}
logger.debug("Starting remote lookup for: " + identifier);
final Map<String, String> params = new HashMap<String, String>();
params.put("userid", identifier.toString());
if(!doRemoteRequest(params))
return null;
final User u = userDao.getUserByIdentifier(identifier);
if(u != null)
logger.info("Successfully imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+identifier+") id: " + u.getId());
else
logger.warn("Failed to import a valid user from remote system: "+identifier);
return u;
}
}

@ -0,0 +1,38 @@
package se.su.dsv.scipro.json;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.util.KeyValuePair;
/**
* Default implementation of IUserLookupFromUsername, queries remote defined by ApplicationSettings via JSon requests.
*/
@Component("userLookupFromUsername")
public class DefaultUserLookupFromUsername extends DefaultUserLookupBase implements IUserLookupFromUsername {
private Logger logger = Logger.getLogger(DefaultUserLookupFromUsername.class);
public User lookup(final KeyValuePair<String> userAtRealm){
if(userAtRealm == null || userAtRealm.getKey() == null){
throw new IllegalStateException("null values for user parameter not allowed");
}
final String user = userAtRealm.getKey();
final String realm = (userAtRealm.getValue()!=null?userAtRealm.getValue().toUpperCase():"DSV.SU.SE");
logger.debug("Starting remote lookup for: " + user + "@"+realm);
final Map<String, String> params = new HashMap<String, String>();
params.put("username", user);
params.put("realm", realm);
if(!doRemoteRequest(params))
return null;
final User u = userDao.getUserByUsername(user,realm);
if(u != null)
logger.info("Successfully imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+user+"@"+realm+") id: " + u.getId());
else
logger.warn("Failed to import a valid user from remote system: "+userAtRealm);
return u;
}
}

@ -1,6 +1,13 @@
package se.su.dsv.scipro.json; package se.su.dsv.scipro.json;
/**
* Generic interface for Remote lookups.
* The recommended way of using this interface is to create specializations
* (see IUserLookupFromIdentifier) that defines the actual parameterized types used, and implement those interfaces in concrete classes.
* @param <T> The return type specifier, implementations are urged to return a null value when a lookup fails.
* @param <E> The lookup parameter, use compound types to support querying on multiple parameters.
*/
public interface ILookup<T, E> { public interface ILookup<T, E> {
public T lookup(E lookupParam) throws Exception; public T lookup(E lookupParam);
} }

@ -1,7 +0,0 @@
package se.su.dsv.scipro.json;
import se.su.dsv.scipro.data.dataobjects.User;
public interface IUserLookup extends ILookup<User, String>{
public User lookup(String username) throws Exception;
}

@ -0,0 +1,11 @@
package se.su.dsv.scipro.json;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* Lookup interface specification for remotely querying for User data.
* See ILookup for more information on the implicit contract of this interface.
*/
public interface IUserLookupFromIdentifier extends ILookup<User,Long>{
public User lookup(final Long identifier);
}

@ -0,0 +1,13 @@
package se.su.dsv.scipro.json;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.util.KeyValuePair;
/**
* Lookup interface specification for remotely querying for User data.
* The supplied parameter is a KeyValuePair<String> where the key-field is the users username and the value-field is the users realm.
* See ILookup for more information on the implicit contract of this interface.
*/
public interface IUserLookupFromUsername extends ILookup<User,KeyValuePair<String>>{
public User lookup(final KeyValuePair<String> userAtRealm);
}

@ -5,8 +5,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.log4j.Level; import org.springframework.beans.factory.annotation.Autowired;
import org.apache.log4j.Logger;
import se.su.dsv.scipro.ApplicationSettings; import se.su.dsv.scipro.ApplicationSettings;
@ -28,13 +27,9 @@ public class ImportWorkerLookup {
*/ */
private ImportWorkerResponseHandler thesesResponseHandler; private ImportWorkerResponseHandler thesesResponseHandler;
private ImportUpdateStatsResponseHandler statsResonseHandler; private ImportUpdateStatsResponseHandler statsResonseHandler;
private ApplicationSettings settings;
private Logger logger; @Autowired
private ApplicationSettings applicationSettings;
public ImportWorkerLookup(){
logger = Logger.getLogger(this.getClass());
}
public void lookup(Date updatedAfter, String type) throws IOException{ public void lookup(Date updatedAfter, String type) throws IOException{
lookup(-1,-1, updatedAfter, type); lookup(-1,-1, updatedAfter, type);
@ -60,7 +55,7 @@ public class ImportWorkerLookup {
}else{ }else{
//logger.log(Level.INFO,"Starting lookup for completeGet=true & type="+type+" & updatedAfter=" + updatedAfter); //logger.log(Level.INFO,"Starting lookup for completeGet=true & type="+type+" & updatedAfter=" + updatedAfter);
} }
RequestSender request = new RequestSender(thesesResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST); RequestSender request = new RequestSender(thesesResponseHandler, applicationSettings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (IOException e) { } catch (IOException e) {
@ -74,7 +69,7 @@ public class ImportWorkerLookup {
params.put("updateStats", "true"); params.put("updateStats", "true");
params.put("updatedAfter",""+updatedAfter.getTime()); params.put("updatedAfter",""+updatedAfter.getTime());
RequestSender request = new RequestSender(statsResonseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST); RequestSender request = new RequestSender(statsResonseHandler, applicationSettings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (IOException e) { } catch (IOException e) {
@ -86,30 +81,18 @@ public class ImportWorkerLookup {
/* /*
* Getters and setters (for spring) * Getters and setters (for spring)
*/ */
public ImportWorkerResponseHandler getUserResponseHandler() { public ImportWorkerResponseHandler getUserResponseHandler() {
return thesesResponseHandler; return thesesResponseHandler;
} }
public void setUserResponseHandler(ImportWorkerResponseHandler thesesResponseHandler) { public void setUserResponseHandler(ImportWorkerResponseHandler thesesResponseHandler) {
this.thesesResponseHandler = thesesResponseHandler; this.thesesResponseHandler = thesesResponseHandler;
} }
public ApplicationSettings getSettings() {
return settings;
}
public void setSettings(ApplicationSettings settings) {
this.settings = settings;
}
public ImportUpdateStatsResponseHandler getStatsResonseHandler() { public ImportUpdateStatsResponseHandler getStatsResonseHandler() {
return statsResonseHandler; return statsResonseHandler;
} }
public void setStatsResonseHandler( public void setStatsResonseHandler(
ImportUpdateStatsResponseHandler statsResonseHandler) { ImportUpdateStatsResponseHandler statsResonseHandler) {
this.statsResonseHandler = statsResonseHandler; this.statsResonseHandler = statsResonseHandler;
} }
} }

@ -5,12 +5,9 @@ import java.util.Iterator;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import se.su.dsv.scipro.ApplicationSettings; import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
@ -36,10 +33,6 @@ import se.su.dsv.scipro.jsonobjects.JsonUsername;
@Component @Component
public abstract class JsonResponseHandler implements IResponseHandler { public abstract class JsonResponseHandler implements IResponseHandler {
/*
* References populated by spring
*/
@Autowired @Autowired
protected UserDao userDao; protected UserDao userDao;
@Autowired @Autowired
@ -52,12 +45,12 @@ public abstract class JsonResponseHandler implements IResponseHandler {
protected ProjectFollowerDao projectFollowerDao; protected ProjectFollowerDao projectFollowerDao;
@Autowired @Autowired
protected RoleDao roleDao; protected RoleDao roleDao;
@SpringBean(name="userLookup") @Autowired
protected IUserLookup userLookup; protected IUserLookupFromIdentifier userLookupFromIdentifier;
@Autowired
protected ApplicationSettings settings; protected ApplicationSettings applicationSettings;
protected Logger logger; protected Logger logger = Logger.getLogger(this.getClass());
private int numUsersCreated = 0; private int numUsersCreated = 0;
private int numEmailChanges = 0; private int numEmailChanges = 0;
@ -69,12 +62,6 @@ public abstract class JsonResponseHandler implements IResponseHandler {
private int numThesesChanged = 0; private int numThesesChanged = 0;
public JsonResponseHandler(){
super();
logger = Logger.getLogger(this.getClass());
}
/** /**
* Creates a thesis user from a json user * Creates a thesis user from a json user
* *
@ -82,8 +69,6 @@ public abstract class JsonResponseHandler implements IResponseHandler {
* @return User the create thesisuser * @return User the create thesisuser
*/ */
protected User createThesisUser(JsonUser jsonUser, boolean doFullCheck){ protected User createThesisUser(JsonUser jsonUser, boolean doFullCheck){
TransactionStatus status = null;
User thesisUser = null; User thesisUser = null;
try { try {
@ -129,7 +114,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
numUsersCreated++; numUsersCreated++;
} }
catch (Exception e){ catch (Exception e){
logger.log(Level.ERROR, "Cannot save jsonuser with jsonuserid: " + jsonUser.id + " - Rolling back...\n" + e.getMessage()); logger.error("Cannot save jsonuser with jsonuserid: " + jsonUser.id + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return thesisUser; return thesisUser;
@ -168,11 +153,11 @@ public abstract class JsonResponseHandler implements IResponseHandler {
User u = userDao.getUserByIdentifier(jtp.id); User u = userDao.getUserByIdentifier(jtp.id);
if(u == null){ if(u == null){
String id = String.valueOf(jtp.id); final Long id = Long.valueOf(jtp.id);
try { try {
u = userLookup.lookup(id); u = userLookupFromIdentifier.lookup(id);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.ERROR, "Cannot save jsonuser with jsonuserid: " + jtp.id + " - Rolling back...\n" + e.getMessage()); logger.error("Cannot save jsonuser with jsonuserid: " + jtp.id + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
u = userDao.getUserByIdentifier(jtp.id); u = userDao.getUserByIdentifier(jtp.id);
@ -277,7 +262,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
try { try {
checkAndChangeProject(current, jThesis); checkAndChangeProject(current, jThesis);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Error when checking project:" + current.getId()+ "when looking up user:" logger.error("Error when checking project:" + current.getId()+ "when looking up user:"
+jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage()); +jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -286,7 +271,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
try { try {
checkAndCreateProject(jThesis); checkAndCreateProject(jThesis);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Error when creating project: daisyId=" + jThesis.thesisID + "when looking up user:" logger.error("Error when creating project: daisyId=" + jThesis.thesisID + "when looking up user:"
+jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage()); +jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -328,7 +313,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
return true; return true;
} catch (Exception e){ } catch (Exception e){
logger.log(Level.FATAL, "Failed to save changes for user:" + thesisUser.getIdentifier() + " - Rolling back...\n" + e.getMessage()); logger.error("Failed to save changes for user:" + thesisUser.getIdentifier() + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -415,11 +400,11 @@ public abstract class JsonResponseHandler implements IResponseHandler {
for(JsonThesisParticipant jtp : jThesis.participants){ for(JsonThesisParticipant jtp : jThesis.participants){
User u = userDao.getUserByIdentifier(jtp.id); User u = userDao.getUserByIdentifier(jtp.id);
if(u == null){ if(u == null){
String id = String.valueOf(jtp.id); final Long id = Long.valueOf(jtp.id);
try { try {
u = userLookup.lookup(id); u = userLookupFromIdentifier.lookup(id);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Failed to save changes for project:" + current.getIdentifier() + " when looking up user whith idetifier:"+jtp.id+ logger.error("Failed to save changes for project:" + current.getIdentifier() + " when looking up user whith idetifier:"+jtp.id+
" Rolling back...\n" + e.getMessage()); " Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -442,7 +427,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
followers.add(pf); followers.add(pf);
} }
}else{ }else{
logger.log(Level.FATAL, "Failed to save changes for project:" + current.getIdentifier() + "u = null when looking up user whith idetifier:"+jtp.id+ logger.error("Failed to save changes for project:" + current.getIdentifier() + "u = null when looking up user whith idetifier:"+jtp.id+
"- \n Rolling back...\n"); "- \n Rolling back...\n");
} }
} }
@ -491,7 +476,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
projectDao.save(current); projectDao.save(current);
} }
}catch (Exception e){ }catch (Exception e){
logger.log(Level.FATAL, "Failed to save changes for project:" + current.getIdentifier() + " - Rolling back...\n" + e.getMessage()); logger.error("Failed to save changes for project:" + current.getIdentifier() + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return changed; return changed;
@ -510,27 +495,22 @@ public abstract class JsonResponseHandler implements IResponseHandler {
return numUsersCreated; return numUsersCreated;
} }
public int getNumEmailChanges() { public int getNumEmailChanges() {
return numEmailChanges; return numEmailChanges;
} }
public int getNumFirstNameChanges() { public int getNumFirstNameChanges() {
return numFirstNameChanges; return numFirstNameChanges;
} }
public int getNumLastNameChanges() { public int getNumLastNameChanges() {
return numLastNameChanges; return numLastNameChanges;
} }
public int getNumUsernamesAdded() { public int getNumUsernamesAdded() {
return numUsernamesAdded; return numUsernamesAdded;
} }
public int getNumSupervisorsCreated() { public int getNumSupervisorsCreated() {
return numSupervisorsCreated; return numSupervisorsCreated;
} }
@ -538,57 +518,14 @@ public abstract class JsonResponseHandler implements IResponseHandler {
public int getNumThesesCreated() { public int getNumThesesCreated() {
return numThesesCreated; return numThesesCreated;
} }
public void setNumThesesCreated(int numThesesCreated) { public void setNumThesesCreated(int numThesesCreated) {
this.numThesesCreated = numThesesCreated; this.numThesesCreated = numThesesCreated;
} }
public int getNumThesesChanged() { public int getNumThesesChanged() {
return numThesesChanged; return numThesesChanged;
} }
public void setNumThesesChanged(int numThesesChanged) { public void setNumThesesChanged(int numThesesChanged) {
this.numThesesChanged = numThesesChanged; this.numThesesChanged = numThesesChanged;
} }
/*
* Getters and setters (for spring)
*/
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UsernameDao getUsernameDao() {
return userNameDao;
}
public void setUserNameDao(UsernameDao usernameDao) {
this.userNameDao = usernameDao;
}
public ApplicationSettings getSettings() {
return settings;
}
public void setSettings(ApplicationSettings settings) {
this.settings = settings;
}
public IUserLookup getUserLookup() {
return userLookup;
}
public void setUserLookup(IUserLookup userLookup) {
this.userLookup = userLookup;
}
} }

@ -2,7 +2,6 @@ package se.su.dsv.scipro.json;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.apache.log4j.Level;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
@ -23,10 +22,6 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
private boolean logResult = false; private boolean logResult = false;
public JsonUserResponseHandler(){
super();
}
/** /**
* Handles a json string * Handles a json string
* *
@ -37,14 +32,14 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
*/ */
public void handleResponse(String response) { public void handleResponse(String response) {
JsonUserContainer userContainer = null; JsonUserContainer userContainer = null;
logger.debug(response);
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();
Type type = new TypeToken<JsonUserContainer>(){}.getType(); Type type = new TypeToken<JsonUserContainer>(){}.getType();
userContainer = gson.fromJson(response, type); userContainer = gson.fromJson(response, type);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Gson error when creating objects from json \n" + e.getMessage()); logger.error("Gson error when creating objects from json \n" + e.getMessage());
return; return;
} }
int createdUsers = 0; int createdUsers = 0;
@ -53,18 +48,18 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
//Loop all users in the response and look for changes... //Loop all users in the response and look for changes...
for(JsonUser jsonUser : userContainer.users){ for(JsonUser jsonUser : userContainer.users){
//System.out.println("Checking: " + " id: " + daisyUser.id + " firstName: "+ daisyUser.firstName); logger.debug("Checking identifier: " + jsonUser.id);
User thesisUser = userDao.getUserByIdentifier(new Long(jsonUser.id)); User thesisUser = userDao.getUserByIdentifier(Long.valueOf(jsonUser.id));
if(thesisUser == null){ if(thesisUser == null){
//System.out.println("User does not exist... trying to create"); logger.debug("User '"+jsonUser.id+ "' does not exist, trying to create");
if(null == createThesisUser(jsonUser,false)){ if(null == createThesisUser(jsonUser,false)){
userCreationErrors++; userCreationErrors++;
} else { } else {
createdUsers++; createdUsers++;
} }
} else { } else {
//System.out.println("User found, looking for changes..."); logger.debug("User found, looking for changes...");
if(lookForChangesInUserAndSave(jsonUser)){ if(lookForChangesInUserAndSave(jsonUser)){
changedUsers++; changedUsers++;
} }
@ -72,7 +67,7 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
} }
if(logResult){ if(logResult){
logger.log(Level.INFO, "\nResult from userimport/update:\nChecked: " + userContainer.users.size() + " users\n" + logger.info("Result from userimport/update:\nChecked: " + userContainer.users.size() + " users\n" +
"Changed users: " + changedUsers + "\n" + "Changed users: " + changedUsers + "\n" +
"Created users: " + createdUsers + "\n" + "Created users: " + createdUsers + "\n" +
"Number of errors when creating users: " + userCreationErrors + "\n" + "Number of errors when creating users: " + userCreationErrors + "\n" +

@ -27,107 +27,28 @@
<property name="entityManagerFactory" ref="entityManagerFactory" /> <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean> </bean>
<!-- Autowired
"eventDao"
"projectEventDao"
"groupEventDao"
"userDao"
"roleDao"
"projectDao"
"projectClassDao"
"projectScheduleDao"
"projectFollowerDao"
"checkListDao"
"checkListQuestion"
"checkListTemplate"
"checkListAnswer"
"stringResourceDao"
"fileDescriptionDao"
"projectEventTemplateDao"
"scheduleTemplateDao"
"commmentDao"
"boardMessageDao"
"messageBoardDao"
"ratingDao"
"privateMessageDao"
"recipientDao"
"resourceDao"
"supervisorBoardMessageDao"
"supervisorMessageBoardDao"
"tagDao"
"commentThreadDao"
"fileResourceDao"
"linkResourceDao"
"embedResourceDao"
-->
<!-- Peer-related beans, autowired-->
<!--
"answerDao"
"peerQueueDao"
"peerRequestDao"
"peerReviewDao"
"questionDao"
"questionOptionDao"
"reviewRatingDao"
"reviewTemplateDao"
-->
<!-- End of Peer-stuff -->
<bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit" /> <bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit" />
<!-- Defines global settings for the application --> <!-- Defines global settings for the application -->
<bean id="applicationSettings" class="se.su.dsv.scipro.ApplicationSettings"> <bean id="applicationSettings" class="se.su.dsv.scipro.ApplicationSettings">
<!-- Set this line to true if you want to do lookup against daisy if username was not found in db <!-- Set this line to true if you want to do lookup against daisy if username was not found in db
By default it's turned off since we don't have access to the daisy search yet By default it's turned off since we don't have access to the daisy search yet
--> -->
<property name="enableRemoteUserLookup" value="true"></property> <property name="enableRemoteUserLookup" value="true"></property>
<!-- This property points to the location of the daisy json search --> <!-- This property points to the location of the daisy json search -->
<property name="remoteLookupUrl" value="https://thesis.dsv.su.se/match/json" /> <property name="remoteLookupUrl" value="https://thesis3.dsv.su.se/match/json" />
<!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.--> <!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.-->
<property name="acceptExternalAuthentication" value="true"/> <property name="acceptExternalAuthentication" value="true"/>
</bean> </bean>
<!-- Defines the class used for lookup in username against a remote server -->
<!-- Defines the class used for lookup in username against a remote server NOW AUTOWIRED AND DEPRECATED, NOT MAINTAINED-->
<!-- <bean id="userFullLookup" class="se.su.dsv.scipro.json.DefaultUserFullLookup">-->
<!-- <property name="userDao" ref="userDao" />-->
<!-- <property name="settings" ref="applicationSettings" />-->
<!-- <property name="userResponseHandler" ref="jsonUserFullResponseHandler" />-->
<!-- </bean> -->
<!-- Defines the class used for lookup in username against a remote server -->
<bean id="importWorkerLookup" class="se.su.dsv.scipro.json.ImportWorkerLookup"> <bean id="importWorkerLookup" class="se.su.dsv.scipro.json.ImportWorkerLookup">
<property name="settings" ref="applicationSettings" />
<property name="userResponseHandler" ref="importWorkerResponseHandler" /> <property name="userResponseHandler" ref="importWorkerResponseHandler" />
<property name="statsResonseHandler" ref="importStatsResponseHandler" /> <property name="statsResonseHandler" ref="importStatsResponseHandler" />
</bean> </bean>
<!-- The abstract handler for json responses --> <!-- The abstract handler for json responses -->
<bean id="jsonResponseHandler" abstract="true" class="se.su.dsv.scipro.json.JsonResponseHandler"> <bean id="jsonResponseHandler" abstract="true" class="se.su.dsv.scipro.json.JsonResponseHandler" />
<property name="settings" ref="applicationSettings" />
<property name="userLookup" ref="userLookup" />
</bean>
<!-- Defines the class used for lookup in username against a remote server NOW AUTOWIRED AND DEPRECATED, NOT MAINTAINED -->
<!-- <bean id="userLookup" class="se.su.dsv.scipro.json.DefaultUserLookup">-->
<!-- <property name="userDao" ref="userDao" />-->
<!-- <property name="settings" ref="applicationSettings" />-->
<!-- <property name="userResponseHandler" ref="jsonUserResponseHandler" />-->
<!-- </bean> -->
<!-- Handler for json responses regarding users --> <!-- Handler for json responses regarding users -->
<bean id="jsonUserResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.JsonUserResponseHandler" /> <bean id="jsonUserResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.JsonUserResponseHandler" />
<bean id="jsonUserFullResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.JsonUserFullResponseHandler" /> <bean id="jsonUserFullResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.JsonUserFullResponseHandler" />
<bean id="importWorkerResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.ImportWorkerResponseHandler" /> <bean id="importWorkerResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.ImportWorkerResponseHandler" />
<bean id="importStatsResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.ImportUpdateStatsResponseHandler" /> <bean id="importStatsResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.ImportUpdateStatsResponseHandler" />
<!-- <bean class="se.su.dsv.scipro.datainitializers.EventTemplatesInitializer" init-method="dataInit" /> -->
<!-- <bean class="se.su.dsv.scipro.datainitializers.ScheduleTemplateInitializer" init-method="dataInit" />-->
<!-- <bean class="se.su.dsv.scipro.datainitializers.EventDataInitializer" init-method="dataInit" />-->
</beans> </beans>

@ -32,15 +32,18 @@ import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.SysAdmin; import se.su.dsv.scipro.data.dataobjects.SysAdmin;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username; import se.su.dsv.scipro.data.dataobjects.Username;
import se.su.dsv.scipro.json.IUserLookup; import se.su.dsv.scipro.json.IUserLookupFromIdentifier;
import se.su.dsv.scipro.json.IUserLookupFromUsername;
import se.su.dsv.scipro.repository.util.RepositoryManager; import se.su.dsv.scipro.repository.util.RepositoryManager;
import se.su.dsv.scipro.util.KeyValuePair;
public class TestAuthRoutines { public class TestAuthRoutines {
private SciProSession session; private SciProSession session;
private WicketTester wt; private WicketTester wt;
private User user; private User user;
private Role sysAdm; private Role sysAdm;
private IUserLookup fixedLookup; private IUserLookupFromIdentifier fixedLookupFromIdentifier;
private IUserLookupFromUsername fixedLookupFromUsername;
private ApplicationSettings appSettings; private ApplicationSettings appSettings;
@Before @Before
public void init(){ public void init(){
@ -49,10 +52,19 @@ public class TestAuthRoutines {
appSettings = new ApplicationSettings(); appSettings = new ApplicationSettings();
appSettings.setAcceptExternalAuthentication(true); appSettings.setAcceptExternalAuthentication(true);
//Fake a lookup mechanism //Fake a lookup mechanism
fixedLookup = new IUserLookup(){ fixedLookupFromUsername = new IUserLookupFromUsername(){
@Override @Override
public User lookup(String username) throws Exception{ public User lookup(final KeyValuePair<String> userAtRealm){
if(username.equals("kalle-kula")) if(userAtRealm.getKey().equals("kalle-kula"))
return user;
else
return null;
}
};
fixedLookupFromIdentifier = new IUserLookupFromIdentifier(){
@Override
public User lookup(final Long identifier){
if(identifier.equals(666))
return user; return user;
else else
return null; return null;
@ -98,7 +110,8 @@ public class TestAuthRoutines {
ac.putBean("roleDao",mockedRoleDao); ac.putBean("roleDao",mockedRoleDao);
ac.putBean("projectDao",Mockito.mock(ProjectDao.class)); ac.putBean("projectDao",Mockito.mock(ProjectDao.class));
ac.putBean("userSettingsDao",Mockito.mock(UserSettingsDao.class)); ac.putBean("userSettingsDao",Mockito.mock(UserSettingsDao.class));
ac.putBean("userFullLookup",fixedLookup); ac.putBean("userLookupFromUsername",fixedLookupFromIdentifier);
ac.putBean("userLookupFromIdentifier",fixedLookupFromIdentifier);
//Create tester //Create tester
wt = new WicketTester(new SciProApplication(){ wt = new WicketTester(new SciProApplication(){
@Override @Override