Index: kernel/api/src/main/java/org/sakaiproject/site/api/RosterAudit.java =================================================================== --- kernel/api/src/main/java/org/sakaiproject/site/api/RosterAudit.java (revision 0) +++ kernel/api/src/main/java/org/sakaiproject/site/api/RosterAudit.java (working copy) @@ -0,0 +1,51 @@ +/********************************************************************************** + * $URL: https://source.sakaiproject.org/svn/kernel/trunk/api/src/main/java/org/sakaiproject/site/api/RosterAudit.java $ + * $Id: RosterAudit.java $ + *********************************************************************************** + * + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 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.site.api; + +import java.util.List; + +/** + *

+ * RosterAuditService controls calls relating to tracking roster auditing. + *

+ */ +public interface RosterAudit +{ + /** 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 rosterAuditList List of String[] to process + */ + public void addToRosterAuditing(List rosterAuditList); + + /** + * This method will allow registering tools to supply their own location for resource loaders + * @param location + * @return + */ + public Object getResourceLoader(String location); +} Index: kernel/api/src/main/java/org/sakaiproject/site/api/RosterAuditService.java =================================================================== --- kernel/api/src/main/java/org/sakaiproject/site/api/RosterAuditService.java (revision 0) +++ kernel/api/src/main/java/org/sakaiproject/site/api/RosterAuditService.java (working copy) @@ -0,0 +1,59 @@ +/********************************************************************************** + * $URL$ + * $Id$ + *********************************************************************************** + * + * Copyright (c) 2010 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.site.api; + +import java.util.List; + +/** + * Service interface that allows tools to register their own database key and associated text for Roster Auditing + * on Roster's Event Log page + * + */ +public interface RosterAuditService { + + /** Database action value for logging a user was added to a site */ + static final String ROSTER_AUDIT_ACTION_ADD = "A"; + + /** Database action value for logging a user was removed from a site */ + static final String ROSTER_AUDIT_ACTION_REMOVE = "D"; + + /** Database action value for logging a user was updated in a site, typically in a different role */ + static final String ROSTER_AUDIT_ACTION_UPDATE = "U"; + + /** + * Method to register a RosterAudit object + * @param ra + */ + public void register(RosterAudit ra); + + /** + * Gets all RosterAudit objects that have been registered + * @return + */ + public List getRegisteredItems(); + + /** + * Get the keys for all RosterAudit objects that have been registered + * @return + */ + public List getKeys(); +} Index: kernel/kernel-component/src/main/webapp/WEB-INF/site-components.xml =================================================================== --- kernel/kernel-component/src/main/webapp/WEB-INF/site-components.xml (revision 130931) +++ kernel/kernel-component/src/main/webapp/WEB-INF/site-components.xml (working copy) @@ -67,5 +67,19 @@ + + + + ${auto.ddl} + + + + + + + Index: kernel/kernel-impl/src/main/java/org/sakaiproject/site/impl/RosterAuditServiceImpl.java =================================================================== --- kernel/kernel-impl/src/main/java/org/sakaiproject/site/impl/RosterAuditServiceImpl.java (revision 0) +++ kernel/kernel-impl/src/main/java/org/sakaiproject/site/impl/RosterAuditServiceImpl.java (working copy) @@ -0,0 +1,89 @@ +package org.sakaiproject.site.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.sakaiproject.db.api.SqlService; +import org.sakaiproject.site.api.RosterAudit; +import org.sakaiproject.site.api.RosterAuditService; + +public class RosterAuditServiceImpl implements RosterAuditService { + + private List registeredItems = new ArrayList(); + private List keys = new ArrayList(); + + /** + * {@inheritDoc} + */ + public void register(RosterAudit ra) { + getRegisteredItems().add(ra); + getKeys().add(ra.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(), "roster_audits"); + } + } + +} Index: kernel/kernel-impl/src/main/sql/hsqldb/roster_audits.sql =================================================================== --- kernel/kernel-impl/src/main/sql/hsqldb/roster_audits.sql (revision 0) +++ kernel/kernel-impl/src/main/sql/hsqldb/roster_audits.sql (working copy) @@ -0,0 +1,10 @@ +-- SAK-23634 / KNL-1138 - new table to track user add/drop/update actions done in sites +create table ROSTER_AUDITS ( + 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), + CHILD_SITE_ID varchar(255)); \ No newline at end of file Index: kernel/kernel-impl/src/main/sql/mysql/roster_audits.sql =================================================================== --- kernel/kernel-impl/src/main/sql/mysql/roster_audits.sql (revision 0) +++ kernel/kernel-impl/src/main/sql/mysql/roster_audits.sql (working copy) @@ -0,0 +1,10 @@ +-- SAK-23634 / KNL-1138 - new table to track user add/drop/update actions done in sites +create table ROSTER_AUDITS ( + 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 datetime not null, + SOURCE varchar(1), + ACTION_USER_ID varchar(255), + CHILD_SITE_ID varchar(255)); \ No newline at end of file Index: kernel/kernel-impl/src/main/sql/oracle/roster_audits.sql =================================================================== --- kernel/kernel-impl/src/main/sql/oracle/roster_audits.sql (revision 0) +++ kernel/kernel-impl/src/main/sql/oracle/roster_audits.sql (working copy) @@ -0,0 +1,10 @@ +-- SAK-23634 / KNL-1138 - new table to track user add/drop/update actions done in sites +create table ROSTER_AUDITS ( + 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), + CHILD_SITE_ID varchar2(255)); \ No newline at end of file Index: kernel/kernel-util/src/main/java/org/sakaiproject/util/RosterAuditImpl.java =================================================================== --- kernel/kernel-util/src/main/java/org/sakaiproject/util/RosterAuditImpl.java (revision 0) +++ kernel/kernel-util/src/main/java/org/sakaiproject/util/RosterAuditImpl.java (working copy) @@ -0,0 +1,229 @@ +/********************************************************************************** + * $URL: https://source.sakaiproject.org/svn/kernel/trunk/kernel-impl/src/main/java/org/sakaiproject/site/impl/RosterAuditImpl.java $ + * $Id: RosterAuditImpl.java $ + *********************************************************************************** + * + * Copyright (c) 2004, 2005, 2006, 2007, 2008 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.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.component.api.ServerConfigurationService; +import org.sakaiproject.db.api.SqlService; +import org.sakaiproject.site.api.RosterAudit; +import org.sakaiproject.site.api.RosterAuditService; +import org.sakaiproject.user.api.UserNotificationPreferencesRegistration; +import org.sakaiproject.util.ResourceLoader; + +/** + *

+ * BaseSite is a base implementation of the Site API Site. + *

+ */ +public abstract class RosterAuditImpl implements RosterAudit +{ + /** Our log (commons). */ + private static Log M_log = LogFactory.getLog(RosterAuditImpl.class); + + // Services needed + protected SqlService sqlService; + protected RosterAuditService rosterAuditService; + protected ServerConfigurationService serverConfigurationService; + + private String bundleLocation = ""; + private ResourceLoader rl = null; + private String databaseSourceKey = ""; + private String sourceText = ""; + + // flag for telling Roster there's parameters to consider + public boolean hasParameters = false; + + /** RosterAuditService init() */ + public void init() + { + ResourceLoader loader = getLocalResourceLoader(); + if (loader != null) { + this.sourceText = loader.getString(getDatabaseSourceKey()); + } + getRosterAuditService().register(this); + } + + public SqlService getSqlService() { + return sqlService; + } + + public void setSqlService(SqlService sqlService) { + this.sqlService = sqlService; + } + + public RosterAuditService getRosterAuditService() { + return rosterAuditService; + } + + public void setRosterAuditService(RosterAuditService rosterAuditService) { + this.rosterAuditService = rosterAuditService; + } + + public ServerConfigurationService getServerConfigurationService() { + return serverConfigurationService; + } + + public void setServerConfigurationService( + ServerConfigurationService serverConfigurationService) { + this.serverConfigurationService = serverConfigurationService; + } + + /** + * 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 addToRosterAuditing(List rosterAuditList) + { + String writeRosterAuditing = serverConfigurationService.getConfig("roster_event_log", "true"); + + // if this is configured to be false, don't bother writing anything to the database + if ("true".equals(writeRosterAuditing)) + { + // determine which flavor of database we're using + String sqlVendor = sqlService.getVendor(); + + for (String[] auditStrings : rosterAuditList) + { + String siteId = auditStrings[0]; + String username = auditStrings[1]; + String roleName = auditStrings[2]; + String actionTaken = auditStrings[3]; + String source = auditStrings[4]; + String actionUserId = auditStrings[5]; + String childSiteId = auditStrings[6]; + Connection conn = null; + String sql = null; + try + { + conn = sqlService.borrowConnection(); + Object fields[] = new Object[8]; + if ("oracle".equals(sqlVendor)) + { + sql = "insert into ROSTER_AUDITS values (?,?,?,?,to_date(?,'YYYY-MM-DD HH24:MI:SS'),?,?,?)"; + } + else + { + sql = "insert into ROSTER_AUDITS 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; + fields[7] = childSiteId; + sqlService.dbWrite(sql, fields); + } + catch (SQLException e) + { + M_log.warn("ERROR logging information for the Roster Auditing process!", e); + } + finally + { + if (conn!=null) + { + try + { + conn.close(); + } + catch (SQLException e) + { + M_log.warn("Error trying to close the connection in the addToRosterAuditing function."); + } + } + } + } + } + } +}