();
// remove all roles and then add back those that were checked
for (int i = 0; i < participants.size(); i++) {
@@ -7806,6 +7841,9 @@
}
realmEdit.addMember(id, roleId, activeGrant,
fromProvider);
+ String currentUserId = (String) state.getAttribute(STATE_CM_CURRENT_USERID);
+ String[] userAuditString = {s.getId(),participant.getEid(),roleId,userAuditService.USER_AUDIT_ACTION_UPDATE,userAuditRegistration.getDatabaseSourceKey(),currentUserId};
+ userAuditList.add(userAuditString);
// construct the event string
String userUpdatedString = "uid=" + id;
@@ -7864,6 +7902,9 @@
}
realmEdit.removeMember(userId);
usersDeleted.add("uid=" + userId);
+ String currentUserId = (String) state.getAttribute(STATE_CM_CURRENT_USERID);
+ String[] userAuditString = {s.getId(),user.getEid(),role.getId(),userAuditService.USER_AUDIT_ACTION_REMOVE,userAuditRegistration.getDatabaseSourceKey(),currentUserId};
+ userAuditList.add(userAuditString);
}
}
}
@@ -7896,6 +7937,13 @@
}
}
AuthzGroupService.save(realmEdit);
+
+ // do the audit logging - Doing this in one bulk call to the database will cause the actual audit stamp to be off by maybe 1 second at the most
+ // but seems to be a better solution than call this multiple time for every update
+ if (!userAuditList.isEmpty())
+ {
+ userAuditRegistration.addToUserAuditing(userAuditList);
+ }
// then update all related group realms for the role
doUpdate_related_group_participants(s, realmId);
Index: userauditservice/api/pom.xml
===================================================================
--- userauditservice/api/pom.xml (revision 0)
+++ userauditservice/api/pom.xml (working copy)
@@ -0,0 +1,43 @@
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice
+ 2.10-SNAPSHOT
+
+
+ Sakai Userauditservice API (userauditservice-api)
+ org.sakaiproject.userauditservice
+ userauditservice-api
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+ Userauditservice interfaces (API)
+ jar
+
+
+ shared
+
+
+
+
+ org.simpleframework
+ simple-xml
+
+
+
+
+
+
+ ${basedir}/src/java
+
+ **/*.xml
+
+ false
+
+
+
+
Index: userauditservice/api/src/java/org/sakaiproject/userauditservice/api/UserAuditRegistration.java
===================================================================
--- userauditservice/api/src/java/org/sakaiproject/userauditservice/api/UserAuditRegistration.java (revision 0)
+++ userauditservice/api/src/java/org/sakaiproject/userauditservice/api/UserAuditRegistration.java (working copy)
@@ -0,0 +1,57 @@
+/**********************************************************************************
+ * $URL$
+ * $Id$
+ ***********************************************************************************
+ *
+ * Copyright (c) 2013 The Sakai Foundation
+ *
+ * Licensed under the Educational Community License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.opensource.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **********************************************************************************/
+
+package org.sakaiproject.userauditservice.api;
+
+import java.util.List;
+
+/**
+ *
+ * UserAuditRegistrationService controls calls relating to tracking user auditing.
+ *
+ */
+public interface UserAuditRegistration
+{
+ /** One character key a tool will use to show where the change came from */
+ public String getDatabaseSourceKey();
+
+ /** The text to register that will be associated with the databaseSourceKey */
+ public String getSourceText(String[] parameter);
+
+ /**
+ * Processes a list of String[] to add records into the database about
+ * @param userAuditList List of String[] to process
+ */
+ public void addToUserAuditing(List userAuditList);
+
+ /**
+ * Method to delete all the user auditing log entries for a site. Used when deleting a site
+ * @param siteId String site id to delete user auditing logs
+ */
+ public void deleteUserAuditingFromSite(String siteId);
+
+ /**
+ * This method will allow registering tools to supply their own location for resource loaders
+ * @param location
+ * @return
+ */
+ public Object getResourceLoader(String location);
+}
Index: userauditservice/api/src/java/org/sakaiproject/userauditservice/api/UserAuditService.java
===================================================================
--- userauditservice/api/src/java/org/sakaiproject/userauditservice/api/UserAuditService.java (revision 0)
+++ userauditservice/api/src/java/org/sakaiproject/userauditservice/api/UserAuditService.java (working copy)
@@ -0,0 +1,58 @@
+/**********************************************************************************
+ * $URL$
+ * $Id$
+ ***********************************************************************************
+ *
+ * Copyright (c) 2013 The Sakai Foundation
+ *
+ * Licensed under the Educational Community License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.opensource.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **********************************************************************************/
+
+package org.sakaiproject.userauditservice.api;
+
+import java.util.List;
+
+/**
+ * Service interface that allows tools to register their own database key and associated text for User Auditing
+ *
+ */
+public interface UserAuditService {
+
+ /** Database action value for logging a user was added to a site */
+ static final String USER_AUDIT_ACTION_ADD = "A";
+
+ /** Database action value for logging a user was removed from a site */
+ static final String USER_AUDIT_ACTION_REMOVE = "D";
+
+ /** Database action value for logging a user was updated in a site, typically in a different role */
+ static final String USER_AUDIT_ACTION_UPDATE = "U";
+
+ /**
+ * Method to register a UserAuditRegistration object
+ * @param ua
+ */
+ public void register(UserAuditRegistration uar);
+
+ /**
+ * Gets all UserAuditRegistration objects that have been registered
+ * @return
+ */
+ public List getRegisteredItems();
+
+ /**
+ * Get the keys for all UserAuditRegistration objects that have been registered
+ * @return
+ */
+ public List getKeys();
+}
Index: userauditservice/deploy/pom.xml
===================================================================
--- userauditservice/deploy/pom.xml (revision 0)
+++ userauditservice/deploy/pom.xml (working copy)
@@ -0,0 +1,38 @@
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice
+ 2.10-SNAPSHOT
+
+
+ Sakai Userauditservice Deploy POM
+ org.sakaiproject.userauditservice
+ userauditservice-deploy
+ 2.10-SNAPSHOT
+ pom
+
+ Userauditservice deploy POM.
+
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+
+
+ shared
+
+
+
+
+
+ org.simpleframework
+ simple-xml
+ ${sakai.simple-xml.version}
+ compile
+
+
+
+
Index: userauditservice/deploy/shared/pom.xml
===================================================================
--- userauditservice/deploy/shared/pom.xml (revision 0)
+++ userauditservice/deploy/shared/pom.xml (working copy)
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice-deploy
+ 2.10-SNAPSHOT
+
+
+ Sakai userauditservice Shared Deploy
+ org.sakaiproject.userauditservice
+ userauditservice-shared
+ pom
+
+ userauditservice shared deploy POM.
+
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+
+
+ shared
+
+
+
+
+ org.simpleframework
+ simple-xml
+
+
+
\ No newline at end of file
Index: userauditservice/impl/pom.xml
===================================================================
--- userauditservice/impl/pom.xml (revision 0)
+++ userauditservice/impl/pom.xml (working copy)
@@ -0,0 +1,54 @@
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice
+ 2.10-SNAPSHOT
+ ../pom.xml
+
+
+ Sakai Userauditservice Implementation (userauditservice-impl)
+ org.sakaiproject.userauditservice
+ userauditservice-impl
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+ Userauditservice implementation
+ jar
+
+
+
+
+
+
+
+ ${project.groupId}
+ userauditservice-api
+
+
+ org.sakaiproject.kernel
+ sakai-kernel-api
+
+
+
+
+
+
+ ${basedir}/src/java
+
+ **/*.xml
+
+ false
+
+
+ ${basedir}/src/sql
+
+ **/*.sql
+
+
+
+
+
Index: userauditservice/impl/src/java/org/sakaiproject/userauditservice/impl/UserAuditServiceImpl.java
===================================================================
--- userauditservice/impl/src/java/org/sakaiproject/userauditservice/impl/UserAuditServiceImpl.java (revision 0)
+++ userauditservice/impl/src/java/org/sakaiproject/userauditservice/impl/UserAuditServiceImpl.java (working copy)
@@ -0,0 +1,110 @@
+/**********************************************************************************
+ * $URL$
+ * $Id$
+ ***********************************************************************************
+ *
+ * Copyright (c) 2013 The Sakai Foundation
+ *
+ * Licensed under the Educational Community License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.opensource.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **********************************************************************************/
+
+package org.sakaiproject.userauditservice.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.sakaiproject.db.api.SqlService;
+import org.sakaiproject.userauditservice.api.UserAuditRegistration;
+import org.sakaiproject.userauditservice.api.UserAuditService;
+
+public class UserAuditServiceImpl implements UserAuditService {
+
+ private List registeredItems = new ArrayList();
+ private List keys = new ArrayList();
+
+ /**
+ * {@inheritDoc}
+ */
+ public void register(UserAuditRegistration uar) {
+ getRegisteredItems().add(uar);
+ getKeys().add(uar.getDatabaseSourceKey());
+ }
+
+ /**
+ * Setter
+ * @param registeredItems
+ */
+ public void setRegisteredItems(List registeredItems) {
+ this.registeredItems = registeredItems;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getRegisteredItems() {
+ return registeredItems;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getKeys() {
+ return keys;
+ }
+
+ /**
+ * Setter
+ * @param keys
+ */
+ public void setKeys(List keys) {
+ this.keys = keys;
+ }
+
+ /** Dependency: SqlService */
+ protected SqlService m_sqlService = null;
+
+ /**
+ * Dependency: SqlService.
+ *
+ * @param service
+ * The SqlService.
+ */
+ public void setSqlService(SqlService service)
+ {
+ m_sqlService = service;
+ }
+
+ /** Configuration: to run the ddl on init or not. */
+ protected boolean m_autoDdl = false;
+
+ /**
+ * Configuration: to run the ddl on init or not.
+ *
+ * @param value
+ * the auto ddl value.
+ */
+ public void setAutoDdl(String value)
+ {
+ m_autoDdl = Boolean.valueOf(value).booleanValue();
+ }
+
+ public void init() {
+ // if we are auto-creating our schema, check and create
+ if (m_autoDdl)
+ {
+ m_sqlService.ddl(this.getClass().getClassLoader(), "user_audits");
+ }
+ }
+
+}
Index: userauditservice/impl/src/sql/hsqldb/user_audits.sql
===================================================================
--- userauditservice/impl/src/sql/hsqldb/user_audits.sql (revision 0)
+++ userauditservice/impl/src/sql/hsqldb/user_audits.sql (working copy)
@@ -0,0 +1,12 @@
+-- SAK-23634 - new table to track user add/drop/update actions done in sites
+create table USER_AUDITS_LOG (
+ ID bigint generated by default as identity (start with 1),
+ SITE_ID varchar(255) not null,
+ USER_ID varchar(255) not null,
+ ROLE_NAME varchar(255) not null,
+ ACTION_TAKEN varchar(1) not null,
+ AUDIT_STAMP timestamp not null,
+ SOURCE varchar(1),
+ ACTION_USER_ID varchar(255),
+ PRIMARY KEY(ID)
+);
\ No newline at end of file
Index: userauditservice/impl/src/sql/mysql/user_audits.sql
===================================================================
--- userauditservice/impl/src/sql/mysql/user_audits.sql (revision 0)
+++ userauditservice/impl/src/sql/mysql/user_audits.sql (working copy)
@@ -0,0 +1,12 @@
+-- SAK-23634 - new table to track user add/drop/update actions done in sites
+create table USER_AUDITS_LOG (
+ ID bigint AUTO_INCREMENT NOT NULL,
+ SITE_ID varchar(255) not null,
+ USER_ID varchar(255) not null,
+ ROLE_NAME varchar(255) not null,
+ ACTION_TAKEN varchar(1) not null,
+ AUDIT_STAMP timestamp not null,
+ SOURCE varchar(1),
+ ACTION_USER_ID varchar(255),
+ PRIMARY KEY(ID)
+);
\ No newline at end of file
Index: userauditservice/impl/src/sql/oracle/user_audits.sql
===================================================================
--- userauditservice/impl/src/sql/oracle/user_audits.sql (revision 0)
+++ userauditservice/impl/src/sql/oracle/user_audits.sql (working copy)
@@ -0,0 +1,14 @@
+-- SAK-23634 - new table to track user add/drop/update actions done in sites
+create table USER_AUDITS_LOG (
+ ID number(19,0) not null,
+ SITE_ID varchar2(255) not null,
+ USER_ID varchar2(255) not null,
+ ROLE_NAME varchar2(255) not null,
+ ACTION_TAKEN varchar2(1) not null,
+ AUDIT_STAMP timestamp not null,
+ SOURCE varchar2(1),
+ ACTION_USER_ID varchar2(255),
+ PRIMARY KEY(ID)
+);
+
+CREATE SEQUENCE USER_AUDITS_LOG_SEQ;
\ No newline at end of file
Index: userauditservice/pack/pom.xml
===================================================================
--- userauditservice/pack/pom.xml (revision 0)
+++ userauditservice/pack/pom.xml (working copy)
@@ -0,0 +1,41 @@
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice
+ 2.10-SNAPSHOT
+
+
+ Sakai Userauditservice Components Package (userauditservice-pack)
+ org.sakaiproject.userauditservice
+ userauditservice-pack
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+
+ Userauditservice components pack (special Sakai convention).
+
+ sakai-component
+
+
+ components
+
+
+
+
+ ${project.groupId}
+ userauditservice-impl
+ runtime
+
+
+ ${project.groupId}
+ userauditservice-util
+ runtime
+
+
+
+
+
\ No newline at end of file
Index: userauditservice/pack/src/webapp/WEB-INF/components.xml
===================================================================
--- userauditservice/pack/src/webapp/WEB-INF/components.xml (revision 0)
+++ userauditservice/pack/src/webapp/WEB-INF/components.xml (working copy)
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+ ${auto.ddl}
+
+
+
+
+
+
+
Index: userauditservice/pom.xml
===================================================================
--- userauditservice/pom.xml (revision 0)
+++ userauditservice/pom.xml (working copy)
@@ -0,0 +1,100 @@
+
+ 4.0.0
+
+ org.sakaiproject
+ master
+ 2.10-SNAPSHOT
+ ../master/pom.xml
+
+
+ Sakai Userauditservice Base POM (userauditservice)
+ org.sakaiproject.userauditservice
+ userauditservice
+ pom
+ 2.10-SNAPSHOT
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+
+
+ 2.6
+ UTF-8
+
+
+
+ api
+ deploy
+ impl
+ pack
+ tool
+ util
+
+
+
+ scm:svn:https://source.sakaiproject.org/svn/userauditservice/trunk
+ scm:svn:https://source.sakaiproject.org/svn/userauditservice/trunk
+ https://source.sakaiproject.org/svn/userauditservice/trunk
+
+
+
+
+ sakai-site
+ Sakai release Site
+ scpexe://source.sakaiproject.org/var/www/html/release/userauditservice/${project.version}
+
+
+
+
+
+
+ ${project.groupId}
+ userauditservice-api
+ ${project.version}
+ provided
+
+
+ ${project.groupId}
+ userauditservice-impl
+ ${project.version}
+
+
+ org.simpleframework
+ simple-xml
+ ${sakai.simple-xml.version}
+ provided
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ aggregate
+
+ UTF-8
+
+ http://download.oracle.com/javase/6/docs/api/
+ http://docs.oracle.com/javaee/5/api/
+ http://junit.sourceforge.net/javadoc/
+
+ true
+ false
+ 512m
+ -J-Xmx512m -J-XX:MaxPermSize=160m
+
+
+ aggregate
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: userauditservice/tool/pom.xml
===================================================================
--- userauditservice/tool/pom.xml (revision 0)
+++ userauditservice/tool/pom.xml (working copy)
@@ -0,0 +1,59 @@
+
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice
+ 2.10-SNAPSHOT
+ ../pom.xml
+
+
+ Sakai Userauditservice Tool (userauditservice-tool)
+ org.sakaiproject.userauditservice
+ userauditservice-tool
+
+ The Sakai Foundation
+ http://sakaiproject.org/
+
+ 2013
+ war
+
+
+
+ org.sakaiproject.kernel
+ sakai-kernel-api
+
+
+ org.sakaiproject.kernel
+ sakai-component-manager
+
+
+ ${project.groupId}
+ userauditservice-api
+
+
+ ${project.groupId}
+ userauditservice-util
+
+
+ org.sakaiproject.jsf
+ myfaces-widgets-depend
+ pom
+
+
+ org.sakaiproject.jsf
+ jsf-app
+
+
+ javax.faces
+ jsf-api
+
+
+
+
+ javax.servlet.jsp
+ jsp-api
+
+
+
Index: userauditservice/tool/src/bundle/UserAuditMessages.properties
===================================================================
--- userauditservice/tool/src/bundle/UserAuditMessages.properties (revision 0)
+++ userauditservice/tool/src/bundle/UserAuditMessages.properties (working copy)
@@ -0,0 +1,19 @@
+navbar_eventLog=User Audit Log
+
+title_event_log=User Audit Log
+
+# Event Log Text - headers
+event_log_name = Name
+event_log_user_id = User ID
+event_log_role = Role
+event_log_date = Date
+event_log_event = Event
+event_log_source = Source
+
+# Event Log Text - actions
+event_log_add = Add
+event_log_remove = Remove
+event_log_update = Update
+
+# Event Log Text - source texts
+event_log_not_available = n/a
Index: userauditservice/tool/src/java/org/sakaiproject/userauditservice/tool/UserAuditEventLog.java
===================================================================
--- userauditservice/tool/src/java/org/sakaiproject/userauditservice/tool/UserAuditEventLog.java (revision 0)
+++ userauditservice/tool/src/java/org/sakaiproject/userauditservice/tool/UserAuditEventLog.java (working copy)
@@ -0,0 +1,474 @@
+/**********************************************************************************
+ * $URL$
+ * $Id$
+ ***********************************************************************************
+ *
+ * Copyright (c) 2013 The Sakai Foundation
+ *
+ * Licensed under the Educational Community License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.opensource.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **********************************************************************************/
+
+package org.sakaiproject.userauditservice.tool;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.text.Collator;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.sakaiproject.component.cover.ComponentManager;
+import org.sakaiproject.db.api.SqlService;
+import org.sakaiproject.jsf.util.LocaleUtil;
+import org.sakaiproject.site.api.SiteService;
+import org.sakaiproject.tool.api.ToolManager;
+import org.sakaiproject.userauditservice.api.UserAuditRegistration;
+import org.sakaiproject.userauditservice.api.UserAuditService;
+import org.sakaiproject.user.api.User;
+import org.sakaiproject.user.api.UserDirectoryService;
+import org.sakaiproject.user.api.UserNotDefinedException;
+
+public class UserAuditEventLog {
+ private static final Log log = LogFactory.getLog(UserAuditEventLog.class);
+ protected List eventLog = new ArrayList();
+ // Static comparators
+ public static final Comparator displayNameComparatorEL;
+ public static final Comparator userIdComparatorEL;
+ public static final Comparator roleNameComparatorEL;
+ public static final Comparator auditStampComparatorEL;
+ public static final Comparator actionTextComparatorEL;
+ public static final Comparator sourceTextComparatorEL;
+ protected String sortColumn;
+ protected boolean sortAscending;
+ private int totalItems = -1;
+ private int firstItem = 0;
+ private int pageSize = 0;
+ private Map userMap = new HashMap();
+ private transient SqlService sqlService = (SqlService) ComponentManager.get(SqlService.class.getName());
+ private transient UserAuditRegistration userAuditRegistration = (UserAuditRegistration) ComponentManager.get(UserAuditRegistration.class.getName());
+ private transient UserAuditService userAuditService = (UserAuditService) ComponentManager.get(UserAuditService.class.getName());
+ private transient SiteService siteService = (SiteService) ComponentManager.get(SiteService.class.getName());
+ private transient ToolManager toolManager = (ToolManager) ComponentManager.get(ToolManager.class.getName());
+ private transient UserDirectoryService userDirectoryService = (UserDirectoryService) ComponentManager.get(UserDirectoryService.class.getName());
+
+ static {
+ displayNameComparatorEL = new Comparator() {
+ public int compare(EventLog one, EventLog another) {
+ int comparison = one.getUserDisplayName().compareToIgnoreCase(another.getUserDisplayName());
+ return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
+ }
+ };
+
+ userIdComparatorEL = new Comparator() {
+ public int compare(EventLog one, EventLog another) {
+ return Collator.getInstance().compare(one.getUser().getEid(),another.getUser().getEid());
+ }
+ };
+
+ roleNameComparatorEL = new Comparator() {
+ public int compare(EventLog one, EventLog another) {
+ int comparison = Collator.getInstance().compare(one.getRoleName(),another.getRoleName());
+ return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
+ }
+ };
+
+ auditStampComparatorEL = new Comparator() {
+ public int compare(EventLog one, EventLog another) {
+ // calling auditStamp directly so it does a comparison to the actual date versus a string style comparison, which isn't quite right.
+ int comparison = (one.auditStamp.compareTo(another.auditStamp));
+ return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
+ }
+ };
+
+ actionTextComparatorEL = new Comparator() {
+ public int compare(EventLog one, EventLog another) {
+ int comparison = Collator.getInstance().compare(one.getActionText(),another.getActionText());
+ return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
+ }
+ };
+
+ sourceTextComparatorEL = new Comparator() {
+ public int compare(EventLog one, EventLog another) {
+ int comparison = Collator.getInstance().compare(one.getSourceText(),another.getSourceText());
+ return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
+ }
+ };
+ }
+
+ protected Comparator getComparatorEL()
+ {
+ String sortColumn = getSortColumn();
+ Comparator comparator;
+ if ("userDisplayName".equals(sortColumn))
+ {
+ comparator = displayNameComparatorEL;
+ }
+ else if ("userId".equals(sortColumn))
+ {
+ comparator = userIdComparatorEL;
+ }
+ else if("roleName".equals(sortColumn))
+ {
+ comparator = roleNameComparatorEL;
+ }
+ else if("auditStamp".equals(sortColumn))
+ {
+ comparator = auditStampComparatorEL;
+ }
+ else if("actionText".equals(sortColumn))
+ {
+ comparator = actionTextComparatorEL;
+ }
+ else if("sourceText".equals(sortColumn))
+ {
+ comparator = sourceTextComparatorEL;
+ }
+ else
+ {
+ // Default to the sort name
+ comparator = auditStampComparatorEL;
+ }
+ return comparator;
+ }
+
+ public class EventLog {
+ protected String actionTaken;
+ protected String actionText;
+ protected User actionUser;
+ protected Date auditStamp;
+ protected String roleName;
+ protected String source;
+ protected String sourceText;
+ protected User user;
+ protected String userDisplayName;
+
+ /**
+ * Constructs a EventLogImpl.
+ *
+ * @param user - this is a User object for who was add/dropped from a site
+ * @param roleName - the user's role in the site
+ * @param actionTaken - this interprets the A, D, and U and return the appropriate text from the bundle
+ * @param auditStamp - will return a String, although a Date object is passed in. This is the date and time the user was added or dropped from the site
+ * @param source - interprets the letter key registered from a tool and returns the appropriate text from the bundle
+ * @param actionUser - User object for who performed the add/drop action
+ * @param childSiteId - Used for logging something specific with parent/child sites
+ */
+ public EventLog(User user, String roleName, String actionTaken, Date auditStamp, String source, User actionUser) {
+ this.user = user;
+ this.roleName = roleName;
+ this.actionTaken = actionTaken;
+ this.auditStamp = auditStamp;
+ this.source = source;
+ this.actionUser = actionUser;
+ }
+
+ public String getActionTaken() {
+ return actionTaken;
+ }
+
+ public String getActionText() {
+ if (userAuditService.USER_AUDIT_ACTION_ADD.equals(actionTaken))
+ {
+ actionText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_add");
+ }
+ else if (userAuditService.USER_AUDIT_ACTION_REMOVE.equals(actionTaken))
+ {
+ actionText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_remove");
+ }
+ else if (userAuditService.USER_AUDIT_ACTION_UPDATE.equals(actionTaken))
+ {
+ actionText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_update");
+ }
+ return actionText;
+ }
+
+ public User getActionUser() {
+ return actionUser;
+ }
+
+ public String getAuditStamp() {
+ DateFormat df = DateFormat.getDateTimeInstance();
+ return df.format(auditStamp);
+ }
+
+ public String getRoleName() {
+ return roleName;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ public String getSourceText() {
+ for(UserAuditRegistration uar : userAuditService.getRegisteredItems())
+ {
+ if (uar.getDatabaseSourceKey().equals(source))
+ {
+ String[] params = new String[] {actionUser.getSortName(), actionUser.getEid()};
+ sourceText = uar.getSourceText(params);
+ break;
+ }
+ else
+ {
+ // if we didn't find an appropriate source, use the not available option
+ sourceText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_not_available");
+ }
+ }
+
+ return sourceText;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public String getUserDisplayName() {
+ userDisplayName = user.getSortName();
+ return userDisplayName;
+ }
+
+ public void setActionTaken(String actionTaken) {
+ this.actionTaken = actionTaken;
+ }
+
+ public void setActionText(String actionText) {
+ this.actionText = actionText;
+ }
+
+ public void setActionUser(User actionUser) {
+ this.actionUser = actionUser;
+ }
+
+ public void setAuditStamp(Date auditStamp) {
+ this.auditStamp = auditStamp;
+ }
+
+ public void setRoleName(String roleName) {
+ this.roleName = roleName;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public void setSourceText(String sourceText) {
+ this.sourceText = sourceText;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public void setUserDisplayName(String userDisplayName) {
+ this.userDisplayName = userDisplayName;
+ }
+ }
+
+ public List getEventLog() {
+ return eventLog;
+ }
+
+ private void getEvents()
+ {
+ if (this.eventLog == null || this.eventLog.isEmpty())
+ {
+ eventLog = new ArrayList();
+ Connection conn = null;
+ Statement statement = null;
+ ResultSet result = null;
+ String sql = "";
+ String siteId = toolManager.getCurrentPlacement().getContext();
+ try
+ {
+ conn = sqlService.borrowConnection();
+ statement = conn.createStatement();
+ sql = "select * from USER_AUDITS_LOG where SITE_ID = '" + siteId + "' order by AUDIT_STAMP desc";
+ result = statement.executeQuery(sql);
+ while (result.next())
+ {
+ String userId = result.getString("USER_ID");
+ String roleName = result.getString("ROLE_NAME");
+ String actionTaken = result.getString("ACTION_TAKEN");
+ Timestamp auditStamp = result.getTimestamp("AUDIT_STAMP");
+ String source = result.getString("SOURCE");
+ String actionUserId = result.getString("ACTION_USER_ID");
+
+ User cachedUser;
+ if (userMap.containsKey(userId))
+ {
+ cachedUser = userMap.get(userId);
+ }
+ else
+ {
+ cachedUser = userDirectoryService.getUserByEid(userId);
+ userMap.put(userId, cachedUser);
+ }
+
+ if (actionUserId!=null && !"".equals(actionUserId))
+ {
+ User cachedActionUser;
+ if (userMap.containsKey(actionUserId))
+ {
+ cachedActionUser = userMap.get(actionUserId);
+ }
+ else
+ {
+ cachedActionUser = userDirectoryService.getUserByEid(actionUserId);
+ userMap.put(actionUserId, cachedActionUser);
+ }
+ eventLog.add(new EventLog(cachedUser,roleName,actionTaken,auditStamp,source,cachedActionUser));
+ }
+ else
+ {
+ eventLog.add(new EventLog(cachedUser,roleName,actionTaken,auditStamp,source,null));
+ }
+ }
+ }
+ catch (UserNotDefinedException e)
+ {
+ log.warn("ERROR getting the user audit logs!", e);
+ }
+ catch (SQLException e)
+ {
+ log.warn("ERROR getting the user audit logs!", e);
+ }
+ finally
+ {
+ try
+ {
+ if (result!=null)
+ {
+ result.close();
+ }
+ }
+ catch (SQLException e)
+ {
+ log.warn("Error trying to close the result set in the Roster Event Log!", e);
+ }
+ try
+ {
+ if (statement!=null)
+ {
+ statement.close();
+ }
+ }
+ catch (SQLException e)
+ {
+ log.warn("Error trying to close the statement in the Roster Event Log!", e);
+ }
+ try
+ {
+ if (conn!=null)
+ {
+ conn.close();
+ }
+ }
+ catch (SQLException e)
+ {
+ log.warn("Error trying to close the database connection in the Roster Event Log!", e);
+ }
+ }
+ }
+ this.totalItems = eventLog.size();
+ }
+
+ public String getInitValues() {
+ getEvents();
+
+ if (eventLog != null && eventLog.size() >= 1) {
+ Collections.sort(eventLog, getComparatorEL());
+ if(!isSortAscending()) {
+ Collections.reverse(eventLog);
+ }
+ }
+
+ return "";
+ }
+
+ public String getPageTitle() {
+ return LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),
+ "UserAuditMessages", "title_event_log");
+ }
+
+ public String getSortColumn() {
+ if (this.sortColumn == null) {
+ this.sortColumn = "auditStamp";
+ }
+ return this.sortColumn;
+ }
+
+ public boolean isExportablePage() {
+ return false;
+ }
+
+ public boolean isSortAscending() {
+ return sortAscending;
+ }
+
+ public void setEventLog(List eventLog) {
+ this.eventLog = eventLog;
+ }
+
+ public void setSortAscending(boolean sortAscending) {
+ this.sortAscending = sortAscending;
+ }
+
+ public void setSortColumn(String sortColumn) {
+ this.sortColumn = sortColumn;
+ }
+
+ public int getRowsNumber() {
+ if(totalItems <= pageSize){
+ return totalItems;
+ }
+ return pageSize;
+ }
+
+ public int getFirstItem() {
+ return firstItem;
+ }
+
+ public void setFirstItem(int firstItem) {
+ this.firstItem = firstItem;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public int getTotalItems() {
+ return this.totalItems;
+ }
+
+ public void setTotalItems(int totalItems) {
+ this.totalItems = totalItems;
+ }
+}
Index: userauditservice/tool/src/webapp/WEB-INF/faces-config.xml
===================================================================
--- userauditservice/tool/src/webapp/WEB-INF/faces-config.xml (revision 0)
+++ userauditservice/tool/src/webapp/WEB-INF/faces-config.xml (working copy)
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ UserAuditMessages
+
+ en
+
+
+
+
+ eventLog
+ org.sakaiproject.userauditservice.tool.UserAuditEventLog
+ session
+
+
+
+ /eventLog.jsp
+
+
Index: userauditservice/tool/src/webapp/WEB-INF/web.xml
===================================================================
--- userauditservice/tool/src/webapp/WEB-INF/web.xml (revision 0)
+++ userauditservice/tool/src/webapp/WEB-INF/web.xml (working copy)
@@ -0,0 +1,131 @@
+
+
+
+ sakai-useraudit
+ Site User Audit Tool
+
+
+ javax.faces.STATE_SAVING_METHOD
+ server
+
+
+
+ org.apache.myfaces.SERIALIZE_STATE_IN_SESSION
+ false
+
+
+
+ org.apache.myfaces.COMPRESS_STATE_IN_SESSION
+ false
+
+
+
+ org.apache.myfaces.ALLOW_JAVASCRIPT
+ true
+
+
+
+ org.apache.myfaces.DETECT_JAVASCRIPT
+ false
+
+
+
+ org.apache.myfaces.PRETTY_HTML
+ true
+
+
+
+ org.apache.myfaces.AUTO_SCROLL
+ true
+
+
+
+ org.apache.myfaces.webapp.StartupServletContextListener
+
+
+
+ MyFacesExtensionsFilter
+ org.apache.myfaces.webapp.filter.ExtensionsFilter
+
+ maxFileSize
+ 20m
+ Set the size limit for uploaded files.
+ Format: 10 - 10 bytes
+ 10k - 10 KB
+ 10m - 10 MB
+ 1g - 1 GB
+
+
+
+
+
+ MyFacesExtensionsFilter
+ /*
+ REQUEST
+ INCLUDE
+ FORWARD
+
+
+
+ MyFacesExtensionsFilter
+ /faces/myFacesExtensionResource/*
+
+
+
+ Faces Servlet
+ javax.faces.webapp.FacesServlet
+ 2
+
+
+
+ Faces Servlet
+ *.jsf
+
+
+
+ sakai.request
+ org.sakaiproject.util.RequestFilter
+
+
+
+ sakai.request
+ Faces Servlet
+ REQUEST
+ FORWARD
+ INCLUDE
+
+
+
+ org.sakaiproject.util.ToolListener
+
+
+
+ sakai.useraudit
+ org.sakaiproject.userauditservice.tool.servlet.UserAuditJsfTool
+
+ default
+ eventLog
+
+
+ path
+ /
+
+
+ default.last.view
+ false
+
+ 1
+
+
+
+
+
+ *.jsp
+
+
+
+
Index: userauditservice/tool/src/webapp/eventLog.jsp
===================================================================
--- userauditservice/tool/src/webapp/eventLog.jsp (revision 0)
+++ userauditservice/tool/src/webapp/eventLog.jsp (working copy)
@@ -0,0 +1,84 @@
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
+<%@ taglib uri="http://sakaiproject.org/jsf/sakai" prefix="sakai"%>
+<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
+<%
+response.setContentType("text/html; charset=UTF-8");
+%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: userauditservice/tool/src/webapp/tools/sakai.useraudit.xml
===================================================================
--- userauditservice/tool/src/webapp/tools/sakai.useraudit.xml (revision 0)
+++ userauditservice/tool/src/webapp/tools/sakai.useraudit.xml (working copy)
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
Index: userauditservice/util/pom.xml
===================================================================
--- userauditservice/util/pom.xml (revision 0)
+++ userauditservice/util/pom.xml (working copy)
@@ -0,0 +1,72 @@
+
+ 4.0.0
+
+
+ org.sakaiproject.userauditservice
+ userauditservice
+ 2.10-SNAPSHOT
+ ../pom.xml
+
+
+ Sakai Userauditservice Util (userauditservice-util)
+ org.sakaiproject.userauditservice
+ userauditservice-util
+
+ Sakai Project
+ http://sakaiproject.org/
+
+ 2013
+ Userauditservice utility
+ jar
+
+
+
+
+
+
+
+ ${project.groupId}
+ userauditservice-api
+
+
+ org.sakaiproject.kernel
+ sakai-kernel-api
+
+
+ org.sakaiproject.kernel
+ sakai-kernel-storage-util
+
+
+ org.sakaiproject.kernel
+ sakai-component-manager
+
+
+ org.springframework
+ spring-test
+
+
+ org.sakaiproject.jsf
+ jsf-tool
+
+
+ javax.servlet
+ servlet-api
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+
+ ${basedir}/src/java
+
+ **/*.xml
+
+ false
+
+
+
+
Index: userauditservice/util/src/java/org/sakaiproject/userauditservice/util/UserAuditJsfTool.java
===================================================================
--- userauditservice/util/src/java/org/sakaiproject/userauditservice/util/UserAuditJsfTool.java (revision 0)
+++ userauditservice/util/src/java/org/sakaiproject/userauditservice/util/UserAuditJsfTool.java (working copy)
@@ -0,0 +1,325 @@
+/**********************************************************************************
+ * $URL$
+ * $Id$
+ ***********************************************************************************
+ *
+ * Copyright (c) 2013 The Sakai Foundation
+ *
+ * Licensed under the Educational Community License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.opensource.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **********************************************************************************/
+
+package org.sakaiproject.userauditservice.tool.servlet;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.sakaiproject.component.cover.ComponentManager;
+import org.sakaiproject.tool.api.ToolSession;
+import org.sakaiproject.tool.api.SessionManager;
+import org.sakaiproject.tool.api.ActiveTool;
+import org.sakaiproject.tool.api.Tool;
+import org.sakaiproject.tool.api.ToolException;
+import org.sakaiproject.tool.api.ActiveToolManager;
+import org.sakaiproject.tool.api.ToolManager;
+import org.sakaiproject.jsf.util.JsfTool;
+import org.sakaiproject.util.Web;
+
+public class UserAuditJsfTool extends JsfTool {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -976719461956856669L;
+
+ private static final Log logger = LogFactory.getLog(UserAuditJsfTool.class);
+
+ private SessionManager sessionManager;
+
+ private ActiveToolManager activeToolManager;
+
+ private ToolManager toolManager;
+
+ private static final String HELPER_EXT = ".helper";
+
+ private static final String PANEL = "panel";
+
+ private static final String HELPER_SESSION_PREFIX = "session.";
+
+ // FIXME: http://bugs.sakaiproject.org/jira/browse/GM-88
+ private static final String MYFACES_VIEW_COLLECTION = "org.apache.myfaces.application.jsp.JspStateManagerImpl.SERIALIZED_VIEW";
+
+ private static final String STORED_MYFACES_VIEW_COLLECTION = "STORED_"
+ + MYFACES_VIEW_COLLECTION;
+
+ // If this URL is requested, the helper is done and ready to return
+ public static final String HELPER_RETURN_NOTIFICATION = "/returnToSender";
+
+ // Override init to inject necessary components via ComponentManager cover
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+
+ super.init(config);
+
+ sessionManager = (SessionManager) ComponentManager
+ .get("org.sakaiproject.tool.api.SessionManager");
+ activeToolManager = (ActiveToolManager) ComponentManager
+ .get("org.sakaiproject.tool.api.ActiveToolManager");
+ toolManager = (ToolManager) ComponentManager
+ .get("org.sakaiproject.tool.api.ToolManager");
+ }
+
+ @Override
+ protected void dispatch(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ logger.debug("dispatch()");
+
+ String target = req.getPathInfo();
+
+ ToolSession session = sessionManager.getCurrentToolSession();
+
+ if (logger.isDebugEnabled()) {
+ Map reqParms = req.getParameterMap();
+ for(Map.Entry entry : reqParms.entrySet())
+ {
+ String reqParmKey = entry.getKey();
+ StringBuffer sb = new StringBuffer();
+ sb.append("REQ_PARM: ");
+ sb.append(reqParmKey);
+ sb.append(" = ");
+ sb.append('[');
+ String[] reqParm = reqParms.get(reqParmKey);
+ for (int i = 0; i < reqParm.length;) {
+ sb.append(reqParm[i]);
+ if (++i < reqParm.length) {
+ sb.append(", ");
+ }
+ }
+ sb.append(']');
+ logger.debug(sb.toString());
+ }
+ Enumeration sessionParmNames = session.getAttributeNames();
+ while (sessionParmNames.hasMoreElements()) {
+ String sessionParmName = sessionParmNames.nextElement();
+ logger.debug("SESS_PARM: " + sessionParmName + " = "
+ + session.getAttribute(sessionParmName));
+ }
+ }
+
+ // see if this is the helper trying to return to caller
+ if (HELPER_RETURN_NOTIFICATION.equals(target)) {
+ target = (String) session.getAttribute(toolManager.getCurrentTool()
+ .getId()
+ + Tool.HELPER_DONE_URL);
+ if (target != null) {
+
+ // FIXME: Workaround for
+ // http://bugs.sakaiproject.org/jira/browse/GM-88
+ Object viewCollection = session
+ .getAttribute(STORED_MYFACES_VIEW_COLLECTION);
+ if (viewCollection != null) {
+ session.removeAttribute(STORED_MYFACES_VIEW_COLLECTION);
+ session.setAttribute(MYFACES_VIEW_COLLECTION,
+ viewCollection);
+ }
+
+ session.removeAttribute(toolManager.getCurrentTool().getId()
+ + Tool.HELPER_DONE_URL);
+ res.sendRedirect(target);
+ return;
+ }
+ }
+
+ // Need this here until ToolServlet is updated to support this in
+ // sendToHelper method
+ // http://bugs.sakaiproject.org/jira/browse/SAK-9043
+ // http://bugs.sakaiproject.org/jira/browse/GM-69
+ Enumeration params = req.getParameterNames();
+ while (params.hasMoreElements()) {
+ String paramName = params.nextElement();
+ if (paramName.startsWith(HELPER_SESSION_PREFIX)) {
+ String attributeName = paramName
+ .substring(HELPER_SESSION_PREFIX.length());
+ session
+ .setAttribute(attributeName, req
+ .getParameter(paramName));
+ }
+ }
+
+ if (sendToHelper(req, res, target)) {
+ return;
+ }
+
+ // see if we have a resource request - i.e. a path with an extension,
+ // and one that is not the JSF_EXT
+ if (isResourceRequest(target)) {
+ // get a dispatcher to the path
+ RequestDispatcher resourceDispatcher = getServletContext()
+ .getRequestDispatcher(target);
+ if (resourceDispatcher != null) {
+ resourceDispatcher.forward(req, res);
+ return;
+ }
+ }
+
+ if ("Title".equals(req.getParameter(PANEL))) {
+ // This allows only one Title JSF for each tool
+ target = "/title.jsf";
+
+ } else {
+
+ if ((target == null) || "/".equals(target)) {
+ target = computeDefaultTarget();
+
+ // make sure it's a valid path
+ if (!target.startsWith("/")) {
+ target = "/" + target;
+ }
+
+ // now that we've messed with the URL, send a redirect to make
+ // it official
+ res.sendRedirect(Web.returnUrl(req, target));
+ return;
+ }
+
+ // see if we want to change the specifically requested view
+ String newTarget = redirectRequestedTarget(target);
+
+ // make sure it's a valid path
+ if (!newTarget.startsWith("/")) {
+ newTarget = "/" + newTarget;
+ }
+
+ if (!newTarget.equals(target)) {
+ // now that we've messed with the URL, send a redirect to make
+ // it official
+ res.sendRedirect(Web.returnUrl(req, newTarget));
+ return;
+ }
+ target = newTarget;
+
+ // store this
+ if (m_defaultToLastView) {
+ session.setAttribute(LAST_VIEW_VISITED, target);
+ }
+ }
+
+ // add the configured folder root and extension (if missing)
+ target = m_path + target;
+
+ // add the default JSF extension (if we have no extension)
+ int lastSlash = target.lastIndexOf('/');
+ int lastDot = target.lastIndexOf('.');
+ if ((lastDot < 0) || (lastDot < lastSlash)) {
+ target += JSF_EXT;
+ }
+
+ // set the information that can be removed from return URLs
+ req.setAttribute(URL_PATH, m_path);
+ req.setAttribute(URL_EXT, ".jsp");
+
+ // set the sakai request object wrappers to provide the native, not
+ // Sakai set up, URL information
+ // - this assures that the FacesServlet can dispatch to the proper view
+ // based on the path info
+ req.setAttribute(Tool.NATIVE_URL, Tool.NATIVE_URL);
+
+ // TODO: Should setting the HTTP headers be moved up to the portal level
+ // as well?
+ res.setContentType("text/html; charset=UTF-8");
+ res.addDateHeader("Expires", System.currentTimeMillis()
+ - (1000L * 60L * 60L * 24L * 365L));
+ res.addDateHeader("Last-Modified", System.currentTimeMillis());
+ res
+ .addHeader("Cache-Control",
+ "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
+ res.addHeader("Pragma", "no-cache");
+
+ // dispatch to the target
+ /*
+ * M_log.debug("dispatching path: " + req.getPathInfo() + " to: " +
+ * target + " context: " + getServletContext().getServletContextName());
+ */
+
+ RequestDispatcher dispatcher = getServletContext()
+ .getRequestDispatcher(target);
+ dispatcher.forward(req, res);
+
+ // restore the request object
+ req.removeAttribute(Tool.NATIVE_URL);
+ req.removeAttribute(URL_PATH);
+ req.removeAttribute(URL_EXT);
+ }
+
+ protected boolean sendToHelper(HttpServletRequest req,
+ HttpServletResponse res, String target) throws ToolException {
+ if (target == null) {
+ target = "/";
+ }
+
+ // 0 parts means the target was just "/", otherwise parts[0] = "",
+ // parts[1] = item id, parts[2] if present is "edit"...
+ String[] parts = target.split("/");
+
+ if (parts.length < 2) {
+ return false;
+ }
+
+ if (!parts[1].endsWith(HELPER_EXT)) {
+ return false;
+ }
+
+ // calc helper id
+ int posEnd = parts[1].lastIndexOf('.');
+
+ String helperId = target.substring(1, posEnd + 1);
+ ActiveTool helperTool = activeToolManager.getActiveTool(helperId);
+
+ ToolSession toolSession = sessionManager.getCurrentToolSession();
+
+ if (toolSession.getAttribute(helperTool.getId() + Tool.HELPER_DONE_URL) == null) {
+ toolSession.setAttribute(helperTool.getId() + Tool.HELPER_DONE_URL,
+ req.getContextPath() + req.getServletPath()
+ + computeDefaultTarget());
+ }
+
+ String context = req.getContextPath() + req.getServletPath()
+ + Web.makePath(parts, 1, 2);
+ String toolPath = Web.makePath(parts, 2, parts.length);
+
+ // FIXME: Workaround for http://bugs.sakaiproject.org/jira/browse/GM-88
+ // Don't overwrite if already stored
+ if (toolSession.getAttribute(STORED_MYFACES_VIEW_COLLECTION) == null) {
+ Object viewCollection = toolSession
+ .getAttribute(MYFACES_VIEW_COLLECTION);
+ if (viewCollection != null) {
+ toolSession.removeAttribute(MYFACES_VIEW_COLLECTION);
+ toolSession.setAttribute(STORED_MYFACES_VIEW_COLLECTION,
+ viewCollection);
+ }
+ }
+
+ helperTool.help(req, res, context, toolPath);
+
+ return true; // was handled as helper call
+ }
+}
Index: userauditservice/util/src/java/org/sakaiproject/userauditservice/util/UserAuditRegistrationUtil.java
===================================================================
--- userauditservice/util/src/java/org/sakaiproject/userauditservice/util/UserAuditRegistrationUtil.java (revision 0)
+++ userauditservice/util/src/java/org/sakaiproject/userauditservice/util/UserAuditRegistrationUtil.java (working copy)
@@ -0,0 +1,243 @@
+/**********************************************************************************
+ * $URL$
+ * $Id$
+ ***********************************************************************************
+ *
+ * Copyright (c) 2013 The Sakai Foundation
+ *
+ * Licensed under the Educational Community License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.opensource.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **********************************************************************************/
+
+package org.sakaiproject.userauditservice.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.sakaiproject.db.api.SqlService;
+import org.sakaiproject.userauditservice.api.UserAuditRegistration;
+import org.sakaiproject.userauditservice.api.UserAuditService;
+import org.sakaiproject.util.ResourceLoader;
+
+/**
+ * UserAuditUtil
+ */
+public class UserAuditRegistrationUtil implements UserAuditRegistration
+{
+ /** Our log (commons). */
+ private static Log M_log = LogFactory.getLog(UserAuditRegistrationUtil.class);
+
+ // Services needed
+ protected SqlService sqlService;
+ protected UserAuditService userAuditService;
+
+ // Other variables
+ private String bundleLocation = "";
+ private ResourceLoader rl = null;
+ private String databaseSourceKey = "";
+ private String sourceText = "";
+
+ // flag for telling the UI there's parameters to consider
+ public boolean hasParameters = false;
+
+ /** UserAuditService init() */
+ public void init()
+ {
+ ResourceLoader loader = getLocalResourceLoader();
+ if (loader != null) {
+ this.sourceText = loader.getString(getDatabaseSourceKey());
+ }
+ getUserAuditService().register(this);
+ }
+
+ public SqlService getSqlService() {
+ return sqlService;
+ }
+
+ public void setSqlService(SqlService sqlService) {
+ this.sqlService = sqlService;
+ }
+
+ public UserAuditService getUserAuditService() {
+ return userAuditService;
+ }
+
+ public void setUserAuditService(UserAuditService userAuditService) {
+ this.userAuditService = userAuditService;
+ }
+
+ /**
+ * Get the fully qualified package of where the message bundle is located.
+ * @return
+ */
+ public String getBundleLocation() {
+ return bundleLocation;
+ }
+
+ /**
+ * Setter
+ * @param bundleLocation
+ */
+ public void setBundleLocation(String bundleLocation) {
+ this.bundleLocation = bundleLocation;
+ }
+
+ public ResourceLoader getResourceLoader(String location) {
+ return new ResourceLoader(location);
+ }
+
+ /**
+ * Gets the ResourceLoader specified by the bundleLocation.
+ * @return
+ */
+ private ResourceLoader getLocalResourceLoader() {
+ if (rl == null) {
+ rl = (ResourceLoader)getResourceLoader(getBundleLocation());
+ }
+ return rl;
+ }
+
+ public String getDatabaseSourceKey() {
+ return databaseSourceKey;
+ }
+
+ public void setDatabaseSourceKey(String databaseSourceKey) {
+ this.databaseSourceKey = databaseSourceKey;
+ }
+
+ public String getSourceText(String[] parameter) {
+ if (isHasParameters())
+ {
+ return rl.getFormattedMessage(getDatabaseSourceKey(), parameter);
+ }
+
+ return sourceText;
+ }
+
+ public void setSourceText(String sourceText) {
+ this.sourceText = sourceText;
+ }
+
+ public boolean isHasParameters() {
+ return hasParameters;
+ }
+
+ public void setHasParameters(boolean hasParameters) {
+ this.hasParameters = hasParameters;
+ }
+
+ /** Pass in a List of String[] and this method will process them and write to the database */
+ public void addToUserAuditing(List userAuditList)
+ {
+ // determine which flavor of database we're using
+ String sqlVendor = sqlService.getVendor();
+
+ for (String[] auditStrings : userAuditList)
+ {
+ String siteId = auditStrings[0];
+ String username = auditStrings[1];
+ String roleName = auditStrings[2];
+ String actionTaken = auditStrings[3];
+ String source = auditStrings[4];
+ String actionUserId = auditStrings[5];
+ Connection conn = null;
+ String sql = null;
+ try
+ {
+ conn = sqlService.borrowConnection();
+ Object fields[] = new Object[7];
+ if ("oracle".equals(sqlVendor))
+ {
+ sql = "insert into USER_AUDITS_LOG (ID,SITE_ID,USER_ID,ROLE_NAME,ACTION_TAKEN,AUDIT_STAMP,SOURCE,ACTION_USER_ID) values (USER_AUDITS_LOG_SEQ.nextval,?,?,?,?,to_date(?,'YYYY-MM-DD HH24:MI:SS'),?,?)";
+ }
+ else
+ {
+ sql = "insert into USER_AUDITS_LOG (SITE_ID,USER_ID,ROLE_NAME,ACTION_TAKEN,AUDIT_STAMP,SOURCE,ACTION_USER_ID) values (?,?,?,?,?,?,?)";
+ }
+ fields[0] = siteId;
+ fields[1] = username;
+ fields[2] = roleName;
+ fields[3] = actionTaken;
+ Date currentDate = new Date();
+ DateFormat actionDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String actionDate = actionDateFormat.format(currentDate);
+ fields[4] = actionDate;
+ fields[5] = source;
+ fields[6] = actionUserId;
+ sqlService.dbWrite(sql, fields);
+ }
+ catch (SQLException e)
+ {
+ M_log.warn("ERROR logging information for the User Auditing process!", e);
+ }
+ finally
+ {
+ if (conn!=null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (SQLException e)
+ {
+ M_log.warn("Error trying to close the connection in the addToUserAuditing function.");
+ }
+ }
+ }
+ }
+ }
+
+ /** Method to delete all the user auditing log entries for a site. Used when deleting a site */
+ public void deleteUserAuditingFromSite(String siteId)
+ {
+ Connection conn = null;
+ String sql = null;
+ try
+ {
+ conn = sqlService.borrowConnection();
+ Object fields[] = new Object[1];
+
+ sql = "delete from USER_AUDITS_LOG where SITE_ID = ?";
+
+ fields[0] = siteId;
+ sqlService.dbWrite(sql, fields);
+ }
+ catch (SQLException e)
+ {
+ M_log.warn("ERROR deleting user auditing logs from site: " + siteId, e);
+ }
+ finally
+ {
+ if (conn!=null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (SQLException e)
+ {
+ M_log.warn("Error trying to close the connection in the addToUserAuditing function.");
+ }
+ }
+ }
+ }
+}