- Created skeleton for Foundry base theme

- A bit of formatting for several classes



git-svn-id: https://svn.libreccm.org/ccm/trunk@2976 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2014-11-19 12:59:39 +00:00
parent dfbf54d11e
commit a84f49eed7
35 changed files with 1105 additions and 406 deletions

View File

@ -32,16 +32,17 @@ import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* An in-house implementation of JAAS's <code>LoginContext</code> class. * An in-house implementation of JAAS's <code>LoginContext</code> class. Needed to workaround a bug
* Needed to workaround a bug in JAAS 1.0 that requires LoginModules to be * in JAAS 1.0 that requires LoginModules to be loaded by the system classloader. This class loads
* loaded by the system classloader. This class loads LoginModules using * LoginModules using <code>Class.forName()</code>. The JAAS bug will be fixed in JDK 1.4.
* <code>Class.forName()</code>. The JAAS bug will be fixed in JDK 1.4.
* *
* @author Sameer Ajmani * @author Sameer Ajmani
* @version $Id: LoginContext.java 287 2005-02-22 00:29:02Z sskracic $ * @version $Id: LoginContext.java 287 2005-02-22 00:29:02Z sskracic $
**/ *
*/
public class LoginContext { public class LoginContext {
private final static Logger s_log = Logger.getLogger( LoginContext.class );
private final static Logger s_log = Logger.getLogger(LoginContext.class);
private Subject m_subject; private Subject m_subject;
private CallbackHandler m_handler; private CallbackHandler m_handler;
@ -64,14 +65,15 @@ public class LoginContext {
Subject subject) Subject subject)
throws LoginException { throws LoginException {
this(name, subject, new CallbackHandler() { this(name, subject, new CallbackHandler() {
public void handle(Callback[] cbs)
throws UnsupportedCallbackException { public void handle(Callback[] cbs)
if (cbs.length > 0) { throws UnsupportedCallbackException {
throw new UnsupportedCallbackException if (cbs.length > 0) {
(cbs[0], "CallbackHandler not defined"); throw new UnsupportedCallbackException(cbs[0], "CallbackHandler not defined");
}
} }
}); }
});
} }
/** /**
@ -98,44 +100,37 @@ public class LoginContext {
throw new LoginException("Login config not defined"); throw new LoginException("Login config not defined");
} }
AppConfigurationEntry[] entries = AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
config.getAppConfigurationEntry(name);
if (entries == null) { if (entries == null) {
throw new LoginException throw new LoginException("Login config for '" + name + "' not defined");
("Login config for '"+name+"' not defined");
} }
m_modules = new LoginModule[entries.length]; m_modules = new LoginModule[entries.length];
m_flags = new AppConfigurationEntry.LoginModuleControlFlag m_flags = new AppConfigurationEntry.LoginModuleControlFlag[entries.length];
[entries.length];
for (int i = 0; i < m_modules.length; i++) { for (int i = 0; i < m_modules.length; i++) {
String module = entries[i].getLoginModuleName(); String module = entries[i].getLoginModuleName();
try { try {
m_modules[i] = (LoginModule) m_modules[i] = (LoginModule) Class.forName(module).newInstance();
Class.forName(module).newInstance();
m_modules[i].initialize(m_subject, m_handler, m_shared, m_modules[i].initialize(m_subject, m_handler, m_shared,
entries[i].getOptions()); entries[i].getOptions());
m_flags[i] = entries[i].getControlFlag(); m_flags[i] = entries[i].getControlFlag();
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new KernelLoginException(module+" not found", e); throw new KernelLoginException(module + " not found", e);
} catch (ExceptionInInitializerError e) { } catch (ExceptionInInitializerError e) {
throw new KernelLoginException(module+" initializer error", e); throw new KernelLoginException(module + " initializer error", e);
} catch (LinkageError e) { } catch (LinkageError e) {
throw new KernelLoginException(module+" linkage error", e); throw new KernelLoginException(module + " linkage error", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new KernelLoginException throw new KernelLoginException(module + " illegal access: "
(module+" illegal access: " + "requires public no-argument constructor", e);
+"requires public no-argument constructor", e);
} catch (InstantiationException e) { } catch (InstantiationException e) {
throw new KernelLoginException throw new KernelLoginException(module + " instantiation exception: "
(module+" instantiation exception: " + "requires public no-argument constructor", e);
+"requires public no-argument constructor", e);
} catch (SecurityException e) { } catch (SecurityException e) {
throw new KernelLoginException throw new KernelLoginException(module + " security exception: check permissions", e);
(module+" security exception: check permissions", e);
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new KernelLoginException(module+" not a LoginModule", e); throw new KernelLoginException(module + " not a LoginModule", e);
} }
} }
} }
@ -156,16 +151,15 @@ public class LoginContext {
// login // login
for (int i = 0; i < m_modules.length; i++) { for (int i = 0; i < m_modules.length; i++) {
try { try {
if( s_log.isDebugEnabled() ) { if (s_log.isDebugEnabled()) {
s_log.debug( "Login on " + m_modules[i].getClass().getName() ); s_log.debug("Login on " + m_modules[i].getClass().getName());
} }
m_modules[i].login(); m_modules[i].login();
s_log.debug( "Login succeeded" ); s_log.debug("Login succeeded");
if (m_flags[i] == AppConfigurationEntry if (m_flags[i] == AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT) {
.LoginModuleControlFlag.SUFFICIENT) {
// sufficient module succeeded // sufficient module succeeded
break; // end login break; // end login
} }
@ -174,16 +168,14 @@ public class LoginContext {
first = e; first = e;
} }
if( s_log.isDebugEnabled() ) { if (s_log.isDebugEnabled()) {
s_log.debug( "Login failed: " + m_flags[i], e ); s_log.debug("Login failed: " + m_flags[i], e);
} }
if (m_flags[i] == AppConfigurationEntry if (m_flags[i] == AppConfigurationEntry.LoginModuleControlFlag.REQUIRED) {
.LoginModuleControlFlag.REQUIRED) {
// required module failed // required module failed
gotFailure = true; gotFailure = true;
} else if (m_flags[i] == AppConfigurationEntry } else if (m_flags[i] == AppConfigurationEntry.LoginModuleControlFlag.REQUISITE) {
.LoginModuleControlFlag.REQUISITE) {
// requisite module failed // requisite module failed
gotFailure = true; gotFailure = true;
break; // end login break; // end login
@ -191,29 +183,29 @@ public class LoginContext {
} }
} }
if( s_log.isDebugEnabled() ) { if (s_log.isDebugEnabled()) {
s_log.debug( "gotFailure: " + gotFailure ); s_log.debug("gotFailure: " + gotFailure);
} }
// commit // commit
if (!gotFailure) { if (!gotFailure) {
// We want to report the first interesting exception. If we got here // We want to report the first interesting exception. If we got here
// then login succeeded, so that's no longer interesting. // then login succeeded, so that's no longer interesting.
first = null; first = null;
s_log.debug( "Doing commit" ); s_log.debug("Doing commit");
for (int i = 0; i < m_modules.length; i++) { for (int i = 0; i < m_modules.length; i++) {
try { try {
if( s_log.isDebugEnabled() ) { if (s_log.isDebugEnabled()) {
s_log.debug( "Commit on " + m_modules[i].getClass().getName() ); s_log.debug("Commit on " + m_modules[i].getClass().getName());
} }
m_modules[i].commit(); m_modules[i].commit();
s_log.debug( "Commit succeeded" ); s_log.debug("Commit succeeded");
} catch (LoginException e) { } catch (LoginException e) {
s_log.debug( "Commit failed", e ); s_log.debug("Commit failed", e);
gotFailure = true; gotFailure = true;
if (first == null) { if (first == null) {
@ -227,20 +219,20 @@ public class LoginContext {
// commit failed, fall through to abort // commit failed, fall through to abort
} }
s_log.debug( "Doing abort" ); s_log.debug("Doing abort");
// abort // abort
for (int i = 0; i < m_modules.length; i++) { for (int i = 0; i < m_modules.length; i++) {
try { try {
if( s_log.isDebugEnabled() ) { if (s_log.isDebugEnabled()) {
s_log.debug( "Abort on " + m_modules[i].getClass().getName() ); s_log.debug("Abort on " + m_modules[i].getClass().getName());
} }
m_modules[i].abort(); m_modules[i].abort();
s_log.debug( "Abort succeeded" ); s_log.debug("Abort succeeded");
} catch (LoginException e) { } catch (LoginException e) {
s_log.debug( "Abort failed", e ); s_log.debug("Abort failed", e);
gotFailure = true; gotFailure = true;
if (first == null) { if (first == null) {
@ -274,4 +266,5 @@ public class LoginContext {
throw first; throw first;
} }
} }
} }

View File

@ -57,8 +57,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* Provides methods for logging in and logging out the current user and * Provides methods for logging in and logging out the current user and accessing the user ID.
* accessing the user ID.
* *
* @author Sameer Ajmani * @author Sameer Ajmani
* @version $Id: UserContext.java 1498 2007-03-19 16:22:15Z apevec $ * @version $Id: UserContext.java 1498 2007-03-19 16:22:15Z apevec $
@ -102,31 +101,28 @@ public class UserContext {
} }
/** /**
* Loads the values for this <code>UserContext</code> from the given * Loads the values for this <code>UserContext</code> from the given Subject.
* Subject.
*/ */
private void loadValues(Subject subject) private void loadValues(Subject subject)
throws LoginException { throws LoginException {
// read the user ID (m_user loaded in getUser) // read the user ID (m_user loaded in getUser)
m_userID = getUserID(subject); m_userID = getUserID(subject);
s_log.debug("userID == "+m_userID); s_log.debug("userID == " + m_userID);
// check whether recovering from forgotten password // check whether recovering from forgotten password
m_recovering = RecoveryLoginModule m_recovering = RecoveryLoginModule
.isRecovering(subject); .isRecovering(subject);
s_log.debug("recovering == "+m_recovering); s_log.debug("recovering == " + m_recovering);
// read set of URL params provided by login modules // read set of URL params provided by login modules
m_params = subject.getPublicCredentials(ParameterData.class); m_params = subject.getPublicCredentials(ParameterData.class);
s_log.debug("params.size == "+m_params.size()); s_log.debug("params.size == " + m_params.size());
} }
/** /**
* Creates a user context from an HTTP request. Attempts to log in the * Creates a user context from an HTTP request. Attempts to log in the user automatically to
* user automatically to load the user ID. Code should access this * load the user ID. Code should access this class using
* class using
* <code>KernelHelper.getKernelRequestContext(req).getUserContext()</code>. * <code>KernelHelper.getKernelRequestContext(req).getUserContext()</code>.
* *
* @throws RedirectException if the user should be redirected to the * @throws RedirectException if the user should be redirected to the login page.
* login page.
*/ */
public UserContext(HttpServletRequest req, public UserContext(HttpServletRequest req,
HttpServletResponse res) HttpServletResponse res)
@ -144,7 +140,7 @@ public class UserContext {
* *
* @throws AccountNotFoundException if the target user does not exist. * @throws AccountNotFoundException if the target user does not exist.
* *
* @throws LoginException if login(User) fails. * @throws LoginException if login(User) fails.
*/ */
public void login(String username) public void login(String username)
throws LoginException { throws LoginException {
@ -153,8 +149,7 @@ public class UserContext {
login(UserAuthentication.retrieveForLoginName(username).getUser()); login(UserAuthentication.retrieveForLoginName(username).getUser());
s_log.debug("SUCCESS login(username)"); s_log.debug("SUCCESS login(username)");
} catch (DataObjectNotFoundException e) { } catch (DataObjectNotFoundException e) {
throw new AccountNotFoundException throw new AccountNotFoundException("user " + username + " does not exist", e);
("user "+username+" does not exist", e);
} }
} }
@ -165,7 +160,7 @@ public class UserContext {
* *
* @throws AccountNotFoundException if the target user does not exist. * @throws AccountNotFoundException if the target user does not exist.
* *
* @throws LoginException if login(User) fails. * @throws LoginException if login(User) fails.
*/ */
public void login(BigDecimal userID) public void login(BigDecimal userID)
throws LoginException { throws LoginException {
@ -174,8 +169,7 @@ public class UserContext {
login(User.retrieve(userID)); login(User.retrieve(userID));
s_log.debug("SUCCESS login(userID)"); s_log.debug("SUCCESS login(userID)");
} catch (DataObjectNotFoundException e) { } catch (DataObjectNotFoundException e) {
throw new AccountNotFoundException throw new AccountNotFoundException("user " + userID + " does not exist", e);
("user "+userID+" does not exist", e);
} }
} }
@ -184,10 +178,10 @@ public class UserContext {
* *
* @param target the User to become * @param target the User to become
* *
* @throws FailedLoginException if the current user is not logged in, * @throws FailedLoginException if the current user is not logged in, doesn't exist, or doesn't
* doesn't exist, or doesn't have admin privileges on the target user. * have admin privileges on the target user.
* *
* @throws LoginException if an error occurs. * @throws LoginException if an error occurs.
*/ */
public void login(User target) public void login(User target)
throws LoginException { throws LoginException {
@ -207,29 +201,27 @@ public class UserContext {
// Now we check whether the target user is banned. If they are then // Now we check whether the target user is banned. If they are then
// it is not possible to become this user. This situation will be // it is not possible to become this user. This situation will be
// generally avoided by hiding the 'become user' link for banned users // generally avoided by hiding the 'become user' link for banned users
if(Kernel.getSecurityConfig().isUserBanOn() && target.isBanned()) { if (Kernel.getSecurityConfig().isUserBanOn() && target.isBanned()) {
throw new LoginException("This user is currently banned"); throw new LoginException("This user is currently banned");
} }
PermissionDescriptor superuser = new PermissionDescriptor PermissionDescriptor superuser = new PermissionDescriptor(PrivilegeDescriptor.ADMIN, target,
(PrivilegeDescriptor.ADMIN, target, user); user);
if (!PermissionService.checkPermission(superuser)) { if (!PermissionService.checkPermission(superuser)) {
s_log.debug("FAILURE login(User): insufficient privileges"); s_log.debug("FAILURE login(User): insufficient privileges");
SecurityLogger.warn("user " + user.getID() SecurityLogger.warn("user " + user.getID()
+ " failed to log in as user " + " failed to log in as user "
+ target.getID() + target.getID()
+ " due to insufficient privileges"); + " due to insufficient privileges");
throw new FailedLoginException throw new FailedLoginException("insufficient privileges to become target user");
("insufficient privileges to become target user");
} }
// set the target user ID in the Subject and login // set the target user ID in the Subject and login
Subject subject = new Subject(); Subject subject = new Subject();
subject.getPrincipals().add(new PartyPrincipal(target.getID())); subject.getPrincipals().add(new PartyPrincipal(target.getID()));
CallbackHandler handler = new RequestCallbackHandler(); CallbackHandler handler = new RequestCallbackHandler();
LoginContext context = new LoginContext LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, subject, handler);
(REQUEST_LOGIN_CONTEXT, subject, handler);
clearValues(); clearValues();
context.login(); context.login();
loadValues(context.getSubject()); loadValues(context.getSubject());
@ -249,8 +241,7 @@ public class UserContext {
/** /**
* Determines whether the user is logged in. * Determines whether the user is logged in.
* *
* @return <code>true</code> if the user is logged in, * @return <code>true</code> if the user is logged in, <code>false</code> otherwise.
* <code>false</code> otherwise.
*/ */
public boolean isLoggedIn() { public boolean isLoggedIn() {
return (m_userID != null); return (m_userID != null);
@ -259,15 +250,14 @@ public class UserContext {
/** /**
* Determines whether the user is recovering a forgotten password. * Determines whether the user is recovering a forgotten password.
* *
* @return <code>true</code> if the user is recovering, * @return <code>true</code> if the user is recovering, <code>false</code> otherwise.
* <code>false</code> otherwise.
*/ */
public boolean isRecovering() { public boolean isRecovering() {
return m_recovering; return m_recovering;
} }
/** /**
* Returns URL parameters that authenticate this user. Package-private. * Returns URL parameters that authenticate this user. Package-private.
* *
* @return an unmodifiable set of bebop ParameterData. * @return an unmodifiable set of bebop ParameterData.
*/ */
@ -276,22 +266,18 @@ public class UserContext {
} }
/** /**
* Returns the set of all possible URL params used by UserContext. * Returns the set of all possible URL params used by UserContext. Package-private.
* Package-private.
* *
* @return an unmodifiable set of bebop ParameterModels. * @return an unmodifiable set of bebop ParameterModels.
*/ */
static Set getModels() { static Set getModels() {
try { try {
// LoginModules add ParameterModels to Subject in initialize() // LoginModules add ParameterModels to Subject in initialize()
LoginContext context = LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT);
new LoginContext(REQUEST_LOGIN_CONTEXT); return Collections.unmodifiableSet(context.getSubject().getPublicCredentials(
return Collections.unmodifiableSet ParameterModel.class));
(context.getSubject().getPublicCredentials
(ParameterModel.class));
} catch (LoginException e) { } catch (LoginException e) {
throw new UncheckedWrapperException throw new UncheckedWrapperException("Could not load context", e);
("Could not load context", e);
} }
} }
@ -310,12 +296,10 @@ public class UserContext {
} }
/** /**
* Returns a User object for the current user. Subsequent calls to this * Returns a User object for the current user. Subsequent calls to this method return references
* method return references to the same User object until the * to the same User object until the <code>logout</code> method is called.
* <code>logout</code> method is called.
* *
* @return the User object for the logged in user or null if the * @return the User object for the logged in user or null if the user is not found.
* user is not found.
* *
* @throws IllegalStateException if the user is not logged in. * @throws IllegalStateException if the user is not logged in.
*/ */
@ -337,11 +321,10 @@ public class UserContext {
} }
/** /**
* Logs in the user from data in the current request. Checks the * Logs in the user from data in the current request. Checks the session ID using
* session ID using <code>SessionContext</code>. * <code>SessionContext</code>.
* *
* @throws RedirectException if the user should be redirected to the * @throws RedirectException if the user should be redirected to the login page.
* login page.
*/ */
private void login() private void login()
throws RedirectException { throws RedirectException {
@ -357,8 +340,8 @@ public class UserContext {
// Check that the user making this request is not banned. If they // Check that the user making this request is not banned. If they
// are we logout the context and throw an exception. // are we logout the context and throw an exception.
if(Kernel.getSecurityConfig().isUserBanOn() if (Kernel.getSecurityConfig().isUserBanOn()
&& User.retrieve(m_userID).isBanned()) { && User.retrieve(m_userID).isBanned()) {
context.logout(); context.logout();
throw new LoginException("This user is banned"); throw new LoginException("This user is banned");
} }
@ -378,8 +361,8 @@ public class UserContext {
if (!success) { if (!success) {
// common code for all exception cases // common code for all exception cases
if (Util.getSecurityHelper().requiresLogin(m_req)) { if (Util.getSecurityHelper().requiresLogin(m_req)) {
s_log.debug("This request requires logging in; " + s_log.debug("This request requires logging in; "
"requesting redirect to login UI"); + "requesting redirect to login UI");
redirectToLoginPage(m_req); redirectToLoginPage(m_req);
} else { } else {
s_log.debug("This request does not require logging in"); s_log.debug("This request does not require logging in");
@ -400,6 +383,7 @@ public class UserContext {
*/ */
private class RequestCallbackHandler private class RequestCallbackHandler
implements CallbackHandler { implements CallbackHandler {
String m_username = null; String m_username = null;
char[] m_password = null; char[] m_password = null;
@ -408,20 +392,19 @@ public class UserContext {
// HTTP Basic Authentication // HTTP Basic Authentication
String auth = m_req.getHeader("Authorization"); String auth = m_req.getHeader("Authorization");
if ((auth == null) if ((auth == null)
|| !auth.toUpperCase().startsWith("BASIC")) { || !auth.toUpperCase().startsWith("BASIC")) {
return; return;
} }
String encoded = auth.substring(6).trim(); // remove "Basic " String encoded = auth.substring(6).trim(); // remove "Basic "
byte[] decoded = new Base64().decode( byte[] decoded = new Base64().decode(
encoded.getBytes(Crypto.CHARACTER_ENCODING)); encoded.getBytes(Crypto.CHARACTER_ENCODING));
String userpass = new String(decoded, Crypto.CHARACTER_ENCODING); String userpass = new String(decoded, Crypto.CHARACTER_ENCODING);
int colon = userpass.indexOf(':'); int colon = userpass.indexOf(':');
if (colon < 0) { if (colon < 0) {
return; return;
} }
m_username = userpass.substring(0, colon); m_username = userpass.substring(0, colon);
m_password = userpass.substring m_password = userpass.substring(colon + 1, userpass.length()).toCharArray();
(colon+1, userpass.length()).toCharArray();
} catch (IOException e) { } catch (IOException e) {
throw new UncheckedWrapperException(e); throw new UncheckedWrapperException(e);
} }
@ -433,32 +416,30 @@ public class UserContext {
for (int i = 0; i < callbacks.length; i++) { for (int i = 0; i < callbacks.length; i++) {
Callback cb = callbacks[i]; Callback cb = callbacks[i];
if (cb instanceof HTTPRequestCallback) { if (cb instanceof HTTPRequestCallback) {
((HTTPRequestCallback)cb).setRequest ((HTTPRequestCallback) cb).setRequest(UserContext.this.m_req);
(UserContext.this.m_req);
} else if (cb instanceof HTTPResponseCallback) { } else if (cb instanceof HTTPResponseCallback) {
((HTTPResponseCallback)cb).setResponse ((HTTPResponseCallback) cb).setResponse(UserContext.this.m_res);
(UserContext.this.m_res);
} else if (cb instanceof LifetimeCallback) { } else if (cb instanceof LifetimeCallback) {
((LifetimeCallback)cb).setForever(false); ((LifetimeCallback) cb).setForever(false);
} else if (cb instanceof NameCallback) { } else if (cb instanceof NameCallback) {
((NameCallback)cb).setName(m_username); ((NameCallback) cb).setName(m_username);
} else if (cb instanceof PasswordCallback) { } else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(m_password); ((PasswordCallback) cb).setPassword(m_password);
} else { } else {
UserContext.reportUnsupportedCallback(cb); UserContext.reportUnsupportedCallback(cb);
} }
} }
} }
} }
/** /**
* Creates a URL to send the user to the login page and then return to * Creates a URL to send the user to the login page and then return to the current page.
* the current page.
* *
* @throws com.arsdigita.web.LoginSignal * @throws com.arsdigita.web.LoginSignal
*/ */
@ -467,25 +448,24 @@ public class UserContext {
} }
/** /**
* Name of the request parameter that stores the URL to return to after * Name of the request parameter that stores the URL to return to after redirecting to the login
* redirecting to the login page. * page.
* *
* @deprecated Use com.arsdigita.ui.login.LoginHelper.RETURN_URL_PARAM_NAME * @deprecated Use com.arsdigita.ui.login.LoginHelper.RETURN_URL_PARAM_NAME instead
* instead
*/ */
public final static String RETURN_URL_PARAM_NAME = "return_url"; public final static String RETURN_URL_PARAM_NAME = "return_url";
/** /**
* Encodes the given request into a return URL parameter. Returns * Encodes the given request into a return URL parameter. Returns
* <code>URLencode(returnURL)</code> where returnURL is * <code>URLencode(returnURL)</code> where returnURL is
* <code>returnURI?key=URLencode(val)&...</code>. The original * <code>returnURI?key=URLencode(val)&...</code>. The original parameter values are
* parameter values are doubly-encoded so that they are decoded * doubly-encoded so that they are decoded appropriately.
* appropriately.
* *
* *
* @param req the request to encode * @param req the request to encode
* *
* @return the URL-encoded parameter * @return the URL-encoded parameter
*
* @deprecated This should be moved to a more appropriate class. * @deprecated This should be moved to a more appropriate class.
*/ */
public static String encodeReturnURL(HttpServletRequest req) { public static String encodeReturnURL(HttpServletRequest req) {
@ -515,33 +495,30 @@ public class UserContext {
} }
/** /**
* Logs in the user. Checks the session ID using * Logs in the user. Checks the session ID using <code>SessionContext</code>.
* <code>SessionContext</code>.
* *
* @param username the user's username * @param username the user's username
* @param password the user's password * @param password the user's password
* @param forever true if the user requests permanent login * @param forever true if the user requests permanent login
* *
* @throws LoginException if login fails. * @throws LoginException if login fails.
*/ */
public void login(String username, public void login(String username,
char[] password, char[] password,
boolean forever) boolean forever)
throws LoginException { throws LoginException {
s_log.debug("START login(username, password, forever)"); s_log.debug("START login(username, password, forever)");
try { try {
CallbackHandler handler = new LoginCallbackHandler CallbackHandler handler = new LoginCallbackHandler(username, password, forever);
(username, password, forever); LoginContext context = new LoginContext(REGISTER_LOGIN_CONTEXT, handler);
LoginContext context = new LoginContext
(REGISTER_LOGIN_CONTEXT, handler);
clearValues(); clearValues();
context.login(); context.login();
// We now check if the user is banned and, if so, we don't allow // We now check if the user is banned and, if so, we don't allow
// the user to login. // the user to login.
if(Kernel.getSecurityConfig().isUserBanOn() if (Kernel.getSecurityConfig().isUserBanOn()
&& UserAuthentication.retrieveForLoginName(username).getUser() && UserAuthentication.retrieveForLoginName(username).getUser()
.isBanned()) { .isBanned()) {
throw new LoginException("This user is currently banned"); throw new LoginException("This user is currently banned");
} }
@ -555,8 +532,9 @@ public class UserContext {
} }
/** /**
* Logs in the user using alternative "RegisterSSO" login context. * Logs in the user using alternative "RegisterSSO" login context. It is expected that SSO token
* It is expected that SSO token is present in the request * is present in the request
*
* @see SimpleSSOLoginModule * @see SimpleSSOLoginModule
* @throws LoginException * @throws LoginException
*/ */
@ -568,7 +546,7 @@ public class UserContext {
CallbackHandler handler = new RequestCallbackHandler(); CallbackHandler handler = new RequestCallbackHandler();
LoginContext context = new LoginContext(REGISTER_SSO_LOGIN_CONTEXT, LoginContext context = new LoginContext(REGISTER_SSO_LOGIN_CONTEXT,
handler); handler);
clearValues(); clearValues();
context.login(); context.login();
@ -602,12 +580,13 @@ public class UserContext {
boolean forever) { boolean forever) {
m_username = username; m_username = username;
m_password = password; m_password = password;
m_forever = forever; m_forever = forever;
} }
/** /**
* *
* @param callbacks * @param callbacks
*
* @throws IOException * @throws IOException
* @throws UnsupportedCallbackException * @throws UnsupportedCallbackException
*/ */
@ -617,27 +596,26 @@ public class UserContext {
for (int i = 0; i < callbacks.length; i++) { for (int i = 0; i < callbacks.length; i++) {
Callback cb = callbacks[i]; Callback cb = callbacks[i];
if (cb instanceof HTTPRequestCallback) { if (cb instanceof HTTPRequestCallback) {
((HTTPRequestCallback)cb).setRequest ((HTTPRequestCallback) cb).setRequest(UserContext.this.m_req);
(UserContext.this.m_req);
} else if (cb instanceof HTTPResponseCallback) { } else if (cb instanceof HTTPResponseCallback) {
((HTTPResponseCallback)cb).setResponse ((HTTPResponseCallback) cb).setResponse(UserContext.this.m_res);
(UserContext.this.m_res);
} else if (cb instanceof LifetimeCallback) { } else if (cb instanceof LifetimeCallback) {
((LifetimeCallback)cb).setForever(m_forever); ((LifetimeCallback) cb).setForever(m_forever);
} else if (cb instanceof NameCallback) { } else if (cb instanceof NameCallback) {
((NameCallback)cb).setName(m_username); ((NameCallback) cb).setName(m_username);
} else if (cb instanceof PasswordCallback) { } else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(m_password); ((PasswordCallback) cb).setPassword(m_password);
} else { } else {
UserContext.reportUnsupportedCallback(cb); UserContext.reportUnsupportedCallback(cb);
} }
} }
} }
} }
/** /**
@ -650,23 +628,22 @@ public class UserContext {
private BigDecimal getUserID(Subject subject) throws LoginException { private BigDecimal getUserID(Subject subject) throws LoginException {
Iterator principals = subject.getPrincipals(PartyPrincipal.class) Iterator principals = subject.getPrincipals(PartyPrincipal.class)
.iterator(); .iterator();
if (!principals.hasNext()) { if (!principals.hasNext()) {
throw new FailedLoginException throw new FailedLoginException("no principal available after login");
("no principal available after login");
} }
return ((PartyPrincipal) principals.next()).getID(); return ((PartyPrincipal) principals.next()).getID();
} }
/** /**
* Logs out the user. Clears the cached User object. Loads a new * Logs out the user. Clears the cached User object. Loads a new session ID using
* session ID using <code>SessionContext</code>. * <code>SessionContext</code>.
* *
* @throws LoginException if logout fails. * @throws LoginException if logout fails.
*/ */
public void logout() throws LoginException { public void logout() throws LoginException {
s_log.debug("START logout"); s_log.debug("START logout");
CallbackHandler handler = new RequestCallbackHandler(); CallbackHandler handler = new RequestCallbackHandler();
@ -679,15 +656,15 @@ public class UserContext {
} }
/** /**
* Reports an unsupported callback to the debug log and throws an * Reports an unsupported callback to the debug log and throws an exception. Package-private.
* exception. Package-private.
* *
* @throws UnsupportedCallbackException with appropriate error message * @throws UnsupportedCallbackException with appropriate error message
*/ */
static void reportUnsupportedCallback(Callback cb) static void reportUnsupportedCallback(Callback cb)
throws UnsupportedCallbackException { throws UnsupportedCallbackException {
s_log.error ("Unsupported callback: " s_log.error("Unsupported callback: "
+(cb == null ? null : cb.getClass().getName())); + (cb == null ? null : cb.getClass().getName()));
throw new UnsupportedCallbackException(cb); throw new UnsupportedCallbackException(cb);
} }
} }

View File

@ -18,8 +18,6 @@
*/ */
package com.arsdigita.ui.admin; package com.arsdigita.ui.admin;
import com.arsdigita.ui.admin.ApplicationsAdministrationTab; import com.arsdigita.ui.admin.ApplicationsAdministrationTab;
import com.arsdigita.bebop.ActionLink; import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.BoxPanel;
@ -53,7 +51,7 @@ import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder; import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.ui.UI ; import com.arsdigita.ui.UI;
import com.arsdigita.web.URL; import com.arsdigita.web.URL;
import com.arsdigita.web.Web; import com.arsdigita.web.Web;
import com.arsdigita.web.RedirectSignal; import com.arsdigita.web.RedirectSignal;
@ -78,23 +76,21 @@ import java.util.ArrayList;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* This pane contains three main segmented panel which only one is visible at * This pane contains three main segmented panel which only one is visible at any given time. The
* any given time. The first panel is a table listing all available users in * first panel is a table listing all available users in the system. The second panel displays read
* the system. The second panel displays read only user information. And the * only user information. And the third panel is edit form.
* third panel is edit form.
* *
* @author David Dao * @author David Dao
* @author Ron Henderson * @author Ron Henderson
* @version $Id: UserBrowsePane.java 1372 2006-11-13 09:22:54Z chrisgilbert23 $ * @version $Id: UserBrowsePane.java 1372 2006-11-13 09:22:54Z chrisgilbert23 $
*/ */
class UserBrowsePane extends SegmentedPanel class UserBrowsePane extends SegmentedPanel
implements TableCellRenderer, implements TableCellRenderer,
TableActionListener, TableActionListener,
Resettable, Resettable,
ActionListener, ActionListener,
AdminConstants, AdminConstants,
ChangeListener { ChangeListener {
private static final Logger s_log = Logger.getLogger(UserBrowsePane.class); private static final Logger s_log = Logger.getLogger(UserBrowsePane.class);
@ -141,26 +137,27 @@ class UserBrowsePane extends SegmentedPanel
} }
/** /**
* Creates a new UserBrowsePane with multiple panels to help * Creates a new UserBrowsePane with multiple panels to help manage various aspects of a user's
* manage various aspects of a user's account. * account.
*/ */
public UserBrowsePane () { public UserBrowsePane() {
m_user = new RequestLocal() { m_user = new RequestLocal() {
protected Object initialValue(PageState ps) {
BigDecimal id = (BigDecimal) ps.getValue(USER_ID_PARAM);
User user; protected Object initialValue(PageState ps) {
BigDecimal id = (BigDecimal) ps.getValue(USER_ID_PARAM);
try { User user;
user = User.retrieve(id);
} catch (DataObjectNotFoundException ex) {
throw new UncheckedWrapperException
("Failed to retrieve user: " + id);
}
return user; try {
user = User.retrieve(id);
} catch (DataObjectNotFoundException ex) {
throw new UncheckedWrapperException("Failed to retrieve user: " + id);
} }
};
return user;
}
};
m_userBrowsePanel = buildUserBrowsePanel(); m_userBrowsePanel = buildUserBrowsePanel();
m_panelList.add(m_userBrowsePanel); m_panelList.add(m_userBrowsePanel);
@ -197,18 +194,19 @@ class UserBrowsePane extends SegmentedPanel
/** /**
* Build the User Information panel * Build the User Information panel
*/ */
private Component buildUserInfoPanel () { private Component buildUserInfoPanel() {
// Edit user link // Edit user link
ActionLink link = new ActionLink ActionLink link = new ActionLink(new Label(new GlobalizedMessage("ui.admin.user.editlink",
(new Label(new GlobalizedMessage("ui.admin.user.editlink", BUNDLE_NAME)));
BUNDLE_NAME)));
link.addActionListener(new ActionListener() { link.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PageState ps = e.getPageState(); public void actionPerformed(ActionEvent e) {
displayEditPanel(ps); PageState ps = e.getPageState();
} displayEditPanel(ps);
}); }
});
link.setClassAttr("actionLink"); link.setClassAttr("actionLink");
@ -229,10 +227,12 @@ class UserBrowsePane extends SegmentedPanel
target.setLabel(user.getName()); target.setLabel(user.getName());
} }
}); });
colPanel.add(userName); colPanel.add(userName);
colPanel.add(new Label(new GlobalizedMessage("ui.admin.user.userinfo.screenname", BUNDLE_NAME))); colPanel.add(new Label(new GlobalizedMessage("ui.admin.user.userinfo.screenname",
BUNDLE_NAME)));
final Label userScreenname = new Label(); final Label userScreenname = new Label();
userScreenname.addPrintListener(new PrintListener() { userScreenname.addPrintListener(new PrintListener() {
@ -244,10 +244,12 @@ class UserBrowsePane extends SegmentedPanel
target.setLabel(user.getScreenName()); target.setLabel(user.getScreenName());
} }
}); });
colPanel.add(userScreenname); colPanel.add(userScreenname);
colPanel.add(new Label(new GlobalizedMessage("ui.admin.user.userinfo.primaryemail", BUNDLE_NAME))); colPanel.add(new Label(new GlobalizedMessage("ui.admin.user.userinfo.primaryemail",
BUNDLE_NAME)));
final Label userEmail = new Label(); final Label userEmail = new Label();
userEmail.addPrintListener(new PrintListener() { userEmail.addPrintListener(new PrintListener() {
@ -259,26 +261,21 @@ class UserBrowsePane extends SegmentedPanel
target.setLabel(user.getPrimaryEmail().getEmailAddress()); target.setLabel(user.getPrimaryEmail().getEmailAddress());
} }
}); });
colPanel.add(userEmail); colPanel.add(userEmail);
panel.add(colPanel); panel.add(colPanel);
panel.add(link); panel.add(link);
return addSegment(USER_INFO_LABEL, panel); return addSegment(USER_INFO_LABEL, panel);
} }
/** /**
* Build the User Edit panel * Build the User Edit panel
*/ */
private Component buildUserEditPanel () { private Component buildUserEditPanel() {
return addSegment return addSegment(USER_EDIT_PANEL_HEADER, new UserEditForm(this));
(USER_EDIT_PANEL_HEADER, new UserEditForm(this));
} }
/** /**
@ -311,65 +308,69 @@ class UserBrowsePane extends SegmentedPanel
BoxPanel p = new BoxPanel(); BoxPanel p = new BoxPanel();
// Update password link // Update password link
ActionLink link = new ActionLink(UPDATE_USER_PASSWORD_LABEL); ActionLink link = new ActionLink(UPDATE_USER_PASSWORD_LABEL);
link.addActionListener(new ActionListener() { link.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PageState ps = e.getPageState(); public void actionPerformed(ActionEvent e) {
displayUserPasswordPanel(ps); PageState ps = e.getPageState();
} displayUserPasswordPanel(ps);
}); }
});
link.setClassAttr("actionLink"); link.setClassAttr("actionLink");
p.add(link); p.add(link);
// Become user link // Become user link
// This will not be shown when the user is banned to prevent security issues // This will not be shown when the user is banned to prevent security issues
link = new ActionLink(BECOME_USER_LABEL){ link = new ActionLink(BECOME_USER_LABEL) {
public boolean isVisible(PageState s) {
if(!super.isVisible(s)) { public boolean isVisible(PageState s) {
return false; if (!super.isVisible(s)) {
} return false;
User u = getUser(s); }
return (!u.isBanned()); User u = getUser(s);
} return (!u.isBanned());
}; }
};
link.setClassAttr("actionLink"); link.setClassAttr("actionLink");
link.addActionListener(new ActionListener() { link.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
PageState state = e.getPageState();
BigDecimal id = (BigDecimal) state.getValue(USER_ID_PARAM);
try { public void actionPerformed(ActionEvent e) {
UserContext uc = Web.getUserContext(); PageState state = e.getPageState();
uc.login(id); BigDecimal id = (BigDecimal) state.getValue(USER_ID_PARAM);
} catch (javax.security.auth.login.LoginException ex) {
throw new UncheckedWrapperException("access denied", ex);
}
// Redirect to workspace URL try {
final String path = UI.getUserRedirectURL(state.getRequest()); UserContext uc = Web.getUserContext();
uc.login(id);
final URL url = URL.there(state.getRequest(), path); } catch (javax.security.auth.login.LoginException ex) {
throw new UncheckedWrapperException("access denied", ex);
throw new RedirectSignal(url, true);
} }
});
// Redirect to workspace URL
final String path = UI.getUserRedirectURL(state.getRequest());
final URL url = URL.there(state.getRequest(), path);
throw new RedirectSignal(url, true);
}
});
p.add(link); p.add(link);
// Show all users // Show all users
link = new ActionLink(new Label(new GlobalizedMessage("ui.admin.user.browselink",
link = new ActionLink(new Label BUNDLE_NAME)));
(new GlobalizedMessage("ui.admin.user.browselink",
BUNDLE_NAME)));
link.setClassAttr("actionLink"); link.setClassAttr("actionLink");
link.addActionListener(new ActionListener() { link.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PageState ps = e.getPageState();
displayUserBrowsePanel(ps);
}
});
p.add(link);
public void actionPerformed(ActionEvent e) {
PageState ps = e.getPageState();
displayUserBrowsePanel(ps);
}
});
p.add(link);
return addSegment(USER_ACTION_PANEL_HEADER, p); return addSegment(USER_ACTION_PANEL_HEADER, p);
} }
@ -379,123 +380,131 @@ class UserBrowsePane extends SegmentedPanel
*/ */
private Component buildExtremeActionPanel() { private Component buildExtremeActionPanel() {
ActionLink deleteLink = new ActionLink(USER_DELETE_LABEL){ ActionLink deleteLink = new ActionLink(USER_DELETE_LABEL) {
public boolean isVisible(PageState s) {
if(!super.isVisible(s)) { public boolean isVisible(PageState s) {
return false; if (!super.isVisible(s)) {
} return false;
}
// We show the delete link if the user has never published an item // We show the delete link if the user has never published an item
// This implicitly checks whether the user is banned - if they // This implicitly checks whether the user is banned - if they
// are deletable they cannot ever have been banned // are deletable they cannot ever have been banned
User u = getUser(s); User u = getUser(s);
return (!hasUserPublishedItems(u)); return (!hasUserPublishedItems(u));
} }
}; };
deleteLink.setClassAttr("actionLink"); deleteLink.setClassAttr("actionLink");
deleteLink.setConfirmation(USER_DELETE_CONFIRMATION.localize().toString()); deleteLink.setConfirmation(USER_DELETE_CONFIRMATION.localize().toString());
deleteLink.addActionListener(new ActionListener() { deleteLink.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
PageState state = e.getPageState();
User user = getUser(state);
// Delete the user's authentication record public void actionPerformed(ActionEvent e) {
try { PageState state = e.getPageState();
UserAuthentication.retrieveForUser(user).delete(); User user = getUser(state);
} catch (DataObjectNotFoundException ex) {
// ignore this
}
// Delete the user's authentication record
try {
UserAuthentication.retrieveForUser(user).delete();
} catch (DataObjectNotFoundException ex) {
// ignore this
}
// Delete the user. This might throw an exception // Delete the user. This might throw an exception
// because of integrity constraints, which will be // because of integrity constraints, which will be
// fixed when we can mark accounts deleted rather // fixed when we can mark accounts deleted rather
// than try to do a "hard delete". For now we'll // than try to do a "hard delete". For now we'll
// just catch the exception and display an error // just catch the exception and display an error
// message, but note that the account is no longer // message, but note that the account is no longer
// available for login. // available for login.
try {
try { user.delete();
user.delete(); displayUserBrowsePanel(state);
displayUserBrowsePanel(state); } catch (PersistenceException ex) {
} catch (PersistenceException ex) { s_log.error("Unable to delete user: " + ex.getMessage());
s_log.error("Unable to delete user: " + displayUserDeleteFailedPanel(state);
ex.getMessage()); }
displayUserDeleteFailedPanel(state);
}
} // End ActionPerformed method } // End ActionPerformed method
} // End of new ActionListener definition } // End of new ActionListener definition
); );
// Add link inside a BoxPanel for correct alignment with other // Add link inside a BoxPanel for correct alignment with other
// page elements. // page elements.
ActionLink banLink = new ActionLink(USER_BAN_LABEL){ ActionLink banLink = new ActionLink(USER_BAN_LABEL) {
public boolean isVisible(PageState s) {
if(!super.isVisible(s)) { public boolean isVisible(PageState s) {
return false; if (!super.isVisible(s)) {
} return false;
}
// We show the ban link if the user is not already banned and has never published // We show the ban link if the user is not already banned and has never published
// an item // an item
User u = getUser(s); User u = getUser(s);
return ((!u.isBanned()) && (hasUserPublishedItems(u))); return ((!u.isBanned()) && (hasUserPublishedItems(u)));
} }
};
banLink.setClassAttr("actionLink"); };
banLink.setConfirmation(USER_BAN_CONFIRMATION.localize().toString()); banLink.setClassAttr("actionLink");
banLink.addActionListener(new ActionListener() { banLink.setConfirmation(USER_BAN_CONFIRMATION.localize().toString());
public void actionPerformed (ActionEvent e) { banLink.addActionListener(new ActionListener() {
PageState state = e.getPageState();
User user = getUser(state); public void actionPerformed(ActionEvent e) {
user.setBanned(true); PageState state = e.getPageState();
user.save(); User user = getUser(state);
} // End ActionPerformed method user.setBanned(true);
} // End of new ActionListener definition user.save();
); } // End ActionPerformed method
} // End of new ActionListener definition
);
ActionLink unbanLink = new ActionLink(USER_UNBAN_LABEL) {
public boolean isVisible(PageState s) {
if (!super.isVisible(s)) {
return false;
}
PageState state = s.getPageState();
User user = getUser(state);
return user.isBanned();
}
};
unbanLink.setClassAttr("actionLink");
unbanLink.setConfirmation(USER_UNBAN_CONFIRMATION.localize().toString());
unbanLink.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PageState state = e.getPageState();
User user = getUser(state);
user.setBanned(false);
user.save();
} // End ActionPerformed method
ActionLink unbanLink = new ActionLink(USER_UNBAN_LABEL){
public boolean isVisible(PageState s) {
if(!super.isVisible(s)) {
return false;
}
PageState state = s.getPageState();
User user = getUser(state);
return user.isBanned();
}
};
unbanLink.setClassAttr("actionLink");
unbanLink.setConfirmation(USER_UNBAN_CONFIRMATION.localize().toString());
unbanLink.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
PageState state = e.getPageState();
User user = getUser(state);
user.setBanned(false);
user.save();
} // End ActionPerformed method
} // End of new ActionListener definition } // End of new ActionListener definition
); );
// Add link inside a BoxPanel for correct alignment with other // Add link inside a BoxPanel for correct alignment with other
// page elements. // page elements.
BoxPanel p = new BoxPanel(); BoxPanel p = new BoxPanel();
p.add(deleteLink); p.add(deleteLink);
p.add(banLink); p.add(banLink);
p.add(unbanLink); p.add(unbanLink);
return addSegment(USER_TAB_EXTREME_ACTION_LABEL, p); return addSegment(USER_TAB_EXTREME_ACTION_LABEL, p);
} }
/** /**
* Build a panel to display an error message when unable to delete * Build a panel to display an error message when unable to delete a user.
* a user.
*/ */
private Component buildUserDeleteFailedPanel() { private Component buildUserDeleteFailedPanel() {
ActionLink link = new ActionLink(USER_ACTION_CONTINUE); ActionLink link = new ActionLink(USER_ACTION_CONTINUE);
link.addActionListener(new ActionListener() { link.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
PageState state = e.getPageState(); public void actionPerformed(ActionEvent e) {
displayUserInfoPanel(state); PageState state = e.getPageState();
} displayUserInfoPanel(state);
}); }
});
Label label = new Label(USER_DELETE_FAILED_MSG); Label label = new Label(USER_DELETE_FAILED_MSG);
label.setClassAttr("deleteFailedMessage"); label.setClassAttr("deleteFailedMessage");
@ -508,11 +517,10 @@ class UserBrowsePane extends SegmentedPanel
} }
/** /**
* Build the Browse User panel. Displays a list of all registered * Build the Browse User panel. Displays a list of all registered users.
* users.
*/ */
private Component buildUserBrowsePanel() { private Component buildUserBrowsePanel() {
String headers[] = new String[] { String headers[] = new String[]{
"ID", "Name", "Screen Name", "Email", "SSO login" "ID", "Name", "Screen Name", "Email", "SSO login"
}; };
@ -525,15 +533,16 @@ class UserBrowsePane extends SegmentedPanel
} }
private class GroupsModelBuilder extends LockableImpl private class GroupsModelBuilder extends LockableImpl
implements ListModelBuilder, AdminConstants { implements ListModelBuilder, AdminConstants {
public ListModel makeModel(List list, PageState state) { public ListModel makeModel(List list, PageState state) {
User user = getUser(state); User user = getUser(state);
GroupCollection groups = user.getGroups(); GroupCollection groups = user.getGroups();
groups.addOrder("lower(name)"); groups.addOrder("lower(name)");
return new PartyListModel(groups); return new PartyListModel(groups);
} }
}
}
void displayUserInfoPanel(PageState ps) { void displayUserInfoPanel(PageState ps) {
hideAll(ps); hideAll(ps);
@ -564,13 +573,12 @@ class UserBrowsePane extends SegmentedPanel
} }
/** /**
* Hides all components of the UserBrowsePane in preparation for * Hides all components of the UserBrowsePane in preparation for turning selected components
* turning selected components back on. * back on.
*/ */
private void hideAll(PageState ps) { private void hideAll(PageState ps) {
for (int i = 0; i < m_panelList.size(); i++) { for (int i = 0; i < m_panelList.size(); i++) {
((Component) m_panelList.get(i)).setVisible ((Component) m_panelList.get(i)).setVisible(ps, false);
(ps, false);
} }
} }
@ -605,76 +613,76 @@ class UserBrowsePane extends SegmentedPanel
displayUserBrowsePanel(ps); displayUserBrowsePanel(ps);
} }
public void setTabbedPane(TabbedPane tabbedPane) {
public void setTabbedPane (TabbedPane tabbedPane) {
m_tabbedPane = tabbedPane; m_tabbedPane = tabbedPane;
} }
public void setGroupAdministrationTab(GroupAdministrationTab public void setGroupAdministrationTab(GroupAdministrationTab groupAdministrationTab) {
groupAdministrationTab) {
m_groupAdministrationTab = groupAdministrationTab; m_groupAdministrationTab = groupAdministrationTab;
} }
public void setSitemapAdministrationTab(ApplicationsAdministrationTab public void setSitemapAdministrationTab(ApplicationsAdministrationTab sitemapAdministrationTab) {
sitemapAdministrationTab) {
m_sitemapAdministrationTab = sitemapAdministrationTab; m_sitemapAdministrationTab = sitemapAdministrationTab;
} }
// This is how we check if a user is banned or not // This is how we check if a user is banned or not
private boolean hasUserPublishedItems(User user) { private boolean hasUserPublishedItems(User user) {
DataQuery query = user.getSession().retrieveQuery("com.arsdigita.versioning.UserPublications"); DataQuery query = user.getSession().retrieveQuery(
query.setParameter("value", new Integer(user.getID().intValue()) ); "com.arsdigita.versioning.UserPublications");
query.next(); query.setParameter("value", new Integer(user.getID().intValue()));
Integer count = (Integer) query.get("theCount"); query.next();
query.close(); Integer count = (Integer) query.get("theCount");
return count.intValue()!=0; query.close();
} return count.intValue() != 0;
}
/** /**
* Display group information panel when a group name is clicked. * Display group information panel when a group name is clicked.
*/ */
public void stateChanged (ChangeEvent e) { public void stateChanged(ChangeEvent e) {
if ( e.getSource() == m_groupList ) { if (e.getSource() == m_groupList) {
if ( m_tabbedPane != null && if (m_tabbedPane != null && m_groupAdministrationTab != null) {
m_groupAdministrationTab != null ) {
PageState ps = e.getPageState(); PageState ps = e.getPageState();
String id = (String) m_groupList.getSelectedKey(ps); String id = (String) m_groupList.getSelectedKey(ps);
if (id != null) { if (id != null) {
Group group = null; Group group = null;
try { try {
group = new Group(new BigDecimal(id)); group = new Group(new BigDecimal(id));
} catch(DataObjectNotFoundException exc) { } catch (DataObjectNotFoundException exc) {
// Silently ignore if group does not exist. // Silently ignore if group does not exist.
} }
m_groupAdministrationTab.setGroup (ps, group); m_groupAdministrationTab.setGroup(ps, group);
m_groupAdministrationTab.displayGroupInfoPanel(ps); m_groupAdministrationTab.displayGroupInfoPanel(ps);
m_tabbedPane.setSelectedIndex (ps, GROUP_TAB_INDEX); m_tabbedPane.setSelectedIndex(ps, GROUP_TAB_INDEX);
} else { } else {
reset(ps); reset(ps);
} }
} }
} }
} }
} }
class UserTableModelBuilder extends LockableImpl implements TableModelBuilder { class UserTableModelBuilder extends LockableImpl implements TableModelBuilder {
public TableModel makeModel(Table t, PageState s) { public TableModel makeModel(Table t, PageState s) {
return new UserTableModel(); return new UserTableModel();
} }
} }
class UserTableModel implements TableModel {
class UserTableModel implements TableModel{
private DataQuery m_coll; private DataQuery m_coll;
public UserTableModel() { public UserTableModel() {
m_coll = SessionManager.getSession().retrieveQuery("com.arsdigita.ui.admin.RetrieveAllUsersInfo"); m_coll = SessionManager.getSession().retrieveQuery(
"com.arsdigita.ui.admin.RetrieveAllUsersInfo");
// some kind of order added - ideally ordering should be by // some kind of order added - ideally ordering should be by
// last name then first name, but query returns both as a single // last name then first name, but query returns both as a single
// item chris.gilbert@westsussex.gov.uk // item chris.gilbert@westsussex.gov.uk
m_coll.addOrder("lower(userDisplayName)"); m_coll.addOrder("lower(userDisplayName)");
} }

View File

@ -51,7 +51,7 @@ public class AtoZObjectList extends AbstractObjectList {
private String m_titleProperty = ACSObject.DISPLAY_NAME; private String m_titleProperty = ACSObject.DISPLAY_NAME;
public void setTitleProperty(String property) { public void setTitleProperty(String property) {
Assert.isLocked(this); //Assert.isLocked(this);
m_titleProperty = property; m_titleProperty = property;
} }

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<foundry:configuration xmlns:foundry="http://foundry.libreccm.org">
<setting id="separator"> -&gt; </setting>
</foundry:configuration>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<foundry:configuration xmlns:foundry="http://foundry.libreccm.org">
<setting id="hint-symbol">&#x24d8;</setting>
</foundry:configuration>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<foundry:configuration xmlns:foundry="http://foundry.libreccm.org">
<setting id="content-view-menu/layout">horizontal</setting>
<setting id="category-step-summary/show-delete-link">false</setting>
</foundry:configuration>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<css-files>
<application name="admin">
<css-file origin="internal">admin.css</css-file>
</application>
<application name="cms-admin">
<css-file origin="internal">admin.css</css-file>
</application>
<application name="navigation">
<css-file>public.css</css-file>
</application>
<default>
<css-file>public.css</css-file>
</default>
</css-files>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<foundry:configuration xmlns:foundry="http://foundry.libreccm.org">
<supported-languages default="de">
<language locale="de"/>
<language locale="en"/>
</supported-languages>
<setting id="theme-mode">master</setting>
<!--
Uncomment the following line if you want to use another theme than the Foundry base theme
as parent theme.
-->
<!--<setting id="parent-theme">foundry</setting>-->
<setting id="site-logo">foundry/images/scientificcms_logo.png</setting>
</foundry:configuration>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<applications>
<!--
<application name = "" page-class=""></application>
-->
<application name="admin" internal="true">admin-layout.xml</application>
<application name="login" internal="true">admin-layout.xml</application>
<application name="navigation" class="portalPage">portal-workspace.xml</application>
<application name="navigation" class="portalGridPage">portal-workspace-grid.xml</application>
<application name="none" class="cms-admin" internal="true">admin-layout.xml</application>
<application name="portal">portal-workspace.xml</application>
<default>default-layout.xml</default>
</applications>
<content-items>
<detail>
<content-item content-type="com.arsdigita.cms.contenttypes.Article">
content-items/article-detail.xml
</content-item>
<content-item content-type="com.arsdigita.cms.contenttypes.Bookmark">
content-items/bookmark-detail.xml
</content-item>
<content-item content-type="com.arsdigita.cms.contenttypes.Event">
content-items/event-detail.xml
</content-item>
<content-item content-type="com.arsdigita.cms.contenttypes.MultiPartArticle">
content-items/mpa-detail.xml
</content-item>
<content-item content-type="com.arsdigita.cms.contenttypes.NewsItem">
content-items/news-detail.xml
</content-item>
<default>content-items/detail-default.xml</default>
</detail>
<link>
<default>content-items/link-default.xml</default>
</link>
<list>
<content-item content-type="com.arsdigita.cms.contenttypes.Article">
content-items/article-list.xml
</content-item>
<content-item content-type="com.arsdigita.cms.contenttypes.MultiPartArticle">
content-items/mpa-list.xml
</content-item>
<default>content-items/list-default.xml</default>
</list>
</content-items>
</templates>

View File

@ -0,0 +1 @@
This directory contains fonts used by the theme

View File

@ -0,0 +1,2 @@
Decorating images for the theme. All other images should be managed using
the CMS

View File

@ -0,0 +1 @@
This directory contains the CSS files for the theme.

View File

@ -0,0 +1,5 @@
/*
Public CSS file
*/

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div class="lead">
<lead-text/>
</div>
<div class="main">
<main-text/>
</div>
</content-item-layout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div class="lead">
<lead-text/>
</div>
</content-item-layout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<bookmark-link>
<a>
<content-item-title/>
</a>
</bookmark-link>
</h2>
<div>
<bookmark-description/>
</div>
</content-item-layout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div>
<show-property name="pageDescription"/>
</div>
</content-item-layout>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div class="lead">
<lead-text/>
</div>
<dl>
<dt>
<show-text module="event">start-date</show-text>
</dt>
<dd>
<start-date>
<date-format default="true">
<iso-date/>
</date-format>
</start-date>
T
<start-time>
<style lang="en" style="12h"/>
<style default="true" style="24h"/>
</start-time>
</dd>
<dt>
<show-text module="event">end-date</show-text>
</dt>
<dd>
<end-date>
<date-format default="true">
<iso-date/>
</date-format>
</end-date>
T
<end-time>
<style lang="en" style="12h"/>
<style default="true" style="24h"/>
</end-time>
</dd>
<dt>
<show-text module="event">location</show-text>
</dt>
<dd>
<location/>
</dd>
<dt>
<show-text module="event">event-type</show-text>
</dt>
<dd>
<event-type/>
</dd>
<dt>
<show-text module="event">main-contributor</show-text>
</dt>
<dd>
<main-contributor/>
</dd>
</dl>
<div class="main">
<main-text/>
</div>
</content-item-layout>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<a>
<content-item-title/>
</a>
</content-item-layout>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
</content-item-layout>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div class="lead">
<mpa-summary/>
</div>
<mpa-sections>
<ul>
<mpa-section>
<li>
<a>
<mpa-section-title/>
</a>
</li>
</mpa-section>
</ul>
</mpa-sections>
<mpa-current-sections>
<mpa-current-section>
<h3>
<mpa-current-section-title/>
</h3>
<div class="main">
<mpa-current-section-content/>
</div>
</mpa-current-section>
</mpa-current-sections>
<div class="mpa-paginator">
<mpa-prev-page-link>
<a>
<show-text module="mpa">mpa/prev-page-link</show-text>
</a>
</mpa-prev-page-link>
<mpa-all-sections-link>
<a>
<show-text module="mpa">mpa/all-sections</show-text>
</a>
</mpa-all-sections-link>
<mpa-next-page-link>
<a>
<show-text module="mpa">mpa/next-page-link</show-text>
</a>
</mpa-next-page-link>
</div>
</content-item-layout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div class="lead">
<mpa-summary/>
</div>
</content-item-layout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<content-item-layout>
<h2>
<content-item-title/>
</h2>
<div class="lead">
<lead-text/>
</div>
<div class="news-date">
<news-date>
<date-format default="true">
<iso-date/>
</date-format>
<date-format lang="de">
<day zero="true"/>.<month zero="true"/>.<year/>
</date-format>
</news-date>
</div>
<div class="main">
<main-text/>
</div>
</content-item-layout>

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<page-layout>
<head>
<title>
<separator>: </separator>
<show-text>layout/page/head/title</show-text>
<show-page-title/>
</title>
<load-css-files/>
</head>
<body>
<nav>
<navigation-home-link>
<a>
<navigation-title/>
</a>
</navigation-home-link>
<h1>
<show-text>layout/page/head/title</show-text>: <show-page-title/>
</h1>
<navigation>
<div class="nav-wrapper">
<navigation-links>
<ul>
<navigation-link>
<li>
<a>
<navigation-link-label/>
</a>
<navigation-sublinks/>
</li>
</navigation-link>
</ul>
</navigation-links>
</div>
</navigation>
<breadcrumbs>
<div id="breadcrumbs">
<breadcrumb-link>
<a>
<breadcrumb-label mode="mark"/>
</a>
</breadcrumb-link>
</div>
<breadcrumb-separator>
<span class="breadcrumb-separator">/</span>
</breadcrumb-separator>
</breadcrumbs>
</nav>
<main>
<div>
<content-item/>
</div>
<div>
<image-attachments>
<image-attachment from="2" to="3">
<img width="320" height="240"/>
</image-attachment>
</image-attachments>
</div>
<div id="item-list-wrapper">
<object-list id="itemList">
<ul>
<object-list-item>
<li>
<content-item mode="list"/>
</li>
</object-list-item>
</ul>
</object-list>
</div>
<div id="news-list-wrapper">
<object-list id="newsList">
<ul>
<object-list-item>
<li>
<pre>news-item</pre>
</li>
</object-list-item>
</ul>
</object-list>
</div>
</main>
<aside>
<related-links>
<ul>
<related-link>
<internal>
<li>
<content-item mode="link"/>
</li>
</internal>
<external>
<li>
<a>
<related-link-title/>
</a>
</li>
</external>
</related-link>
</ul>
</related-links>
<notes>
<div id="notes">
<note>
<div class="note">
<note-content/>
</div>
</note>
</div>
</notes>
</aside>
<footer>
<include file="fragments/footer.xml"/>
<include file="fragments/libreccm.xml" internal="yes"/>
</footer>
</body>
</page-layout>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<fragment-layout>
<div>
<strong>included from <code>fragments/footer.xml</code></strong>
</div>
</fragment-layout>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<page-layout>
<head>
<title>
<separator>: </separator>
<show-text>layout/page/head/title</show-text>
<show-page-title/>
</title>
<load-css-files/>
</head>
<body>
<nav>
<navigation-home-link>
<a>
<navigation-title/>
</a>
</navigation-home-link>
<h1>
<show-text>layout/page/head/title</show-text>: <show-page-title/>
</h1>
<navigation>
<div class="nav-wrapper">
<navigation-links>
<ul>
<navigation-link>
<li>
<a>
<navigation-link-label/>
</a>
<navigation-sublinks/>
</li>
</navigation-link>
</ul>
</navigation-links>
</div>
</navigation>
<breadcrumbs>
<div id="breadcrumbs">
<breadcrumb-link>
<a>
<breadcrumb-label mode="mark"/>
</a>
</breadcrumb-link>
</div>
<breadcrumb-separator>
<span class="breadcrumb-separator">/</span>
</breadcrumb-separator>
</breadcrumbs>
</nav>
<main>
<portal-grid-workspace use-default-styles="true">
<portal-grid-workspace-rows>
<portal-grid-workspace-row>
<portal-grid-workspace-columns>
<portal-grid-workspace-column>
<portal-grid-workspace-column-portlets/>
</portal-grid-workspace-column>
</portal-grid-workspace-columns>
</portal-grid-workspace-row>
</portal-grid-workspace-rows>
</portal-grid-workspace>
</main>
</body>
</page-layout>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<page-layout>
<head>
<title>
<separator>: </separator>
<show-text>layout/page/head/title</show-text>
<show-page-title/>
</title>
<load-css-files/>
</head>
<body>
<nav>
<navigation-home-link>
<a>
<navigation-title/>
</a>
</navigation-home-link>
<h1>
<show-text>layout/page/head/title</show-text>: <show-page-title/>
</h1>
<navigation>
<div class="nav-wrapper">
<navigation-links>
<ul>
<navigation-link>
<li>
<a>
<navigation-link-label/>
</a>
<navigation-sublinks/>
</li>
</navigation-link>
</ul>
</navigation-links>
</div>
</navigation>
<breadcrumbs>
<div id="breadcrumbs">
<breadcrumb-link>
<a>
<breadcrumb-label mode="mark"/>
</a>
</breadcrumb-link>
</div>
<breadcrumb-separator>
<span class="breadcrumb-separator">/</span>
</breadcrumb-separator>
</breadcrumbs>
</nav>
<main>
<portal-workspace>
<portal-admin/>
<portal-list>
<div>
<portal-page-link selected="false">
<not-selected>
<a>
<portal-page-title/>
</a>
</not-selected>
<selected>
<span>
<portal-page-title/>
</span>
</selected>
</portal-page-link>
</div>
<div>
<portal-add-page-link/>
<portal-edit-basic-properties-link/>
</div>
<div>
<portal-edit-form/>
<portal-layout-form/>
</div>
</portal-list>
<divIfNotEmpty id="portal-workspace-edit-links" class="workspace-details">
<portal-workspace-edit-links/>
</divIfNotEmpty>
<portal-workspace-columns use-default-styles="true">
<portal-workspace-column>
<div>
<portal-workspace-portlets/>
</div>
</portal-workspace-column>
</portal-workspace-columns>
</portal-workspace>
</main>
</body>
</page-layout>

View File

@ -0,0 +1 @@
This directory contains static texts in the theme

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
<text id="root">
<translation lang="de">Start</translation>
<translation lang="en">Start</translation>
</text>
</foundry:static-texts>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
<text id="start-date">
<translation lang="de">Beginn</translation>
<translation lang="en">Begin</translation>
</text>
<text id="end-date">
<translation lang="de">Ende</translation>
<translation lang="en">End</translation>
</text>
<text id="location">
<translation lang="de">Veranstaltungsort</translation>
<translation lang="en">Location</translation>
</text>
<text id="main-contributor">
<translation lang="de">Veranstalter</translation>
<translation lang="en">Hosted by</translation>
</text>
<text id="event-type">
<translation lang="de">Art der Veranstaltung</translation>
<translation lang="en">Type of event</translation>
</text>
</foundry:static-texts>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
<text id="layout/page/head/title">
<translation lang="de">Foundry</translation>
<translation lang="en">Foundry</translation>
</text>
<text id="layout/page/skipnav/link">
<translation lang="de">Navigation überspringen</translation>
<translation lang="en">Skip navigation</translation>
</text>
<text id="time/am">
<translation lang="de">a.m.</translation>
<translation lang="en">a.m.</translation>
</text>
<text id="time/pm">
<translation lang="de">p.m.</translation>
<translation lang="en">p.m.</translation>
</text>
</foundry:static-texts>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
<text id="mpa/next-page-link">
<translation lang="de">Nächste Seite</translation>
<translation lang="en">Next page</translation>
</text>
<text id="mpa/prev-page-link">
<translation lang="de">Vorherige Seite</translation>
<translation lang="en">Previous page</translation>
</text>
<text id="mpa/all-sections">
<translation lang="de">Artikel auf einer Seite</translation>
<translation lang="en">Article on one page</translation>
</text>
</foundry:static-texts>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
<text id="admin/link">
<translation lang="de">Administrieren</translation>
<translation lang="en">Admin</translation>
</text>
<text id="admin/title">
<translation lang="de">Administrieren</translation>
<translation lang="en">Admin</translation>
</text>
<text id="edit/link">
<translation lang="de">Bearbeiten</translation>
<translation lang="en">Edit</translation>
</text>
<text id="edit/title">
<translation lang="de">Bearbeiten</translation>
<translation lang="en">Edit</translation>
</text>
<text id="view/link">
<translation lang="de">Ansehen</translation>
<translation lang="en">View</translation>
</text>
<text id="view/title">
<translation lang="de">Ansehen</translation>
<translation lang="en">View</translation>
</text>
</foundry:static-texts>

View File

@ -81,8 +81,16 @@
</a> </a>
<script type="text/javascript"> <script type="text/javascript">
<xsl:value-of select="'$(document).ready(function() {'"/> <xsl:value-of select="'$(document).ready(function() {'"/>
<xsl:value-of select="concat('minimizeImage.restore(&quot;', $imageClass, '&quot;, &quot;', $linkClass ,'&quot;, &quot;', $minimizeLabel, '&quot;, &quot;', $maximizeLabel, '&quot;)')"/> <xsl:value-of select="concat('minimizeImage.restore(&quot;', $imageClass, '&quot;, &quot;', $linkClass ,'&quot;, &quot;', $minimizeLabel, '&quot;, &quot;', $maximizeLabel, '&quot;);')"/>
//alert("window.height(jQuery) = " + $(window).height() + "\nwindow.height = " + window.innerHeight + "\n image.height = " + $(".headerImage").height());
<xsl:value-of select="concat('if($(window).height() &lt; $(&quot;.', $imageClass, '&quot;).height() * 2.1) {')"/>
<xsl:value-of select="concat('minimizeImage.minimize(&quot;', $imageClass, '&quot;, &quot;', $linkClass ,'&quot;, &quot;', $minimizeLabel, '&quot;, &quot;', $maximizeLabel, '&quot;);')"/>
<xsl:value-of select="'}'"/>
<xsl:value-of select="'});'"/> <xsl:value-of select="'});'"/>
</script> </script>
</xsl:template> </xsl:template>