You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2006/06/16 18:29:23 UTC
svn commit: r414856 [2/2] - in /cocoon/branches/BRANCH_2_1_X: ./
src/blocks/auth/ src/blocks/auth/conf/ src/blocks/auth/java/
src/blocks/auth/java/org/ src/blocks/auth/java/org/apache/
src/blocks/auth/java/org/apache/cocoon/ src/blocks/auth/java/org/ap...
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/impl/StandardApplicationManager.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/impl/StandardApplicationManager.java?rev=414856&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/impl/StandardApplicationManager.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/impl/StandardApplicationManager.java Fri Jun 16 09:29:21 2006
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.apache.cocoon.auth.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpSession;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.servlet.CocoonServlet;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.cocoon.auth.Application;
+import org.apache.cocoon.auth.ApplicationManager;
+import org.apache.cocoon.auth.ApplicationUtil;
+import org.apache.cocoon.auth.SecurityHandler;
+import org.apache.cocoon.auth.User;
+
+/**
+ * This is the default implementation of the
+ * {@link org.apache.cocoon.auth.ApplicationManager}.
+ *
+ * @version $Id$
+*/
+public class StandardApplicationManager
+ extends AbstractLogEnabled
+ implements ApplicationManager,
+ Contextualizable,
+ Serviceable,
+ ThreadSafe,
+ Disposable {
+
+ /** The key used to store the login information in the session. */
+ protected static final String LOGIN_INFO_KEY =
+ StandardApplicationManager.class.getName() + "/logininfo";
+
+ /** The prefix used to store the application data object in the session. */
+ protected static final String APPLICATION_KEY_PREFIX =
+ StandardApplicationManager.class.getName() + "/app:";
+
+ /** The component context. */
+ protected Context context;
+
+ /** The service manager. */
+ protected ServiceManager manager;
+
+ /**
+ * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+ */
+ public void contextualize(final Context aContext) throws ContextException {
+ this.context = aContext;
+ try {
+ ServletConfig config =
+ (ServletConfig)this.context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG);
+ config.getServletContext().setAttribute(StandardApplicationManager.class.getName(),
+ this);
+ } catch (ContextException ignore) {
+ // we ignore this if we are not running inside a servlet environment
+ }
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(final ServiceManager aManager) throws ServiceException {
+ this.manager = aManager;
+ }
+
+ /**
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ this.manager = null;
+ }
+
+ /**
+ * Get the application with the given name. This method tries to lookup the
+ * applicating using the current sitemap service manager.
+ * @param appName The name of the application.
+ * @return The application object.
+ * @throws Exception If the application can't be found.
+ */
+ protected Application getApplication(final String appName)
+ throws Exception {
+ final ServiceManager current = (ServiceManager)
+ this.context.get(ContextHelper.CONTEXT_SITEMAP_SERVICE_MANAGER);
+ Object o = current.lookup(Application.class.getName() + '/' + appName);
+ if ( o == null ) {
+ throw new ConfigurationException(
+ "Application '" + appName + "' not found."
+ );
+ }
+ // to avoid messy release stuff later on, we just release the app now
+ // as an application is thread safe this isn't really a problem
+ current.release(o);
+ return (Application)o;
+ }
+
+ /**
+ * @see org.apache.cocoon.auth.ApplicationManager#isLoggedIn(java.lang.String)
+ */
+ public boolean isLoggedIn(final String appName) {
+ Object appData = null;
+ final Map objectModel = ContextHelper.getObjectModel( this.context );
+ final Request req = ObjectModelHelper.getRequest(objectModel);
+ final Session session = req.getSession(false);
+ if ( session != null ) {
+ appData = session.getAttribute(APPLICATION_KEY_PREFIX + appName);
+
+ // if the user is logged in, we set the current application, data and user
+ if ( appData != null ) {
+ try {
+ final Application application = this.getApplication(appName);
+ final User user = (User)session.getAttribute(USER + '-' + appName);
+ final Application oldApp = (Application)objectModel.get(ApplicationManager.APPLICATION);
+ objectModel.put(ApplicationManager.APPLICATION, application);
+ objectModel.put(ApplicationManager.APPLICATION_DATA, appData);
+ objectModel.put(ApplicationManager.USER, user);
+ // notify application
+ // The application is only notified once per request.
+ if ( oldApp == null || !oldApp.equals(application) ) {
+ application.userIsAccessing(user);
+ }
+ } catch (Exception ignore) {
+ throw new CascadingRuntimeException("Unable to get application '"
+ + appName + "'", ignore);
+ }
+ }
+ }
+
+ return (appData != null);
+ }
+
+ /**
+ * @see org.apache.cocoon.auth.ApplicationManager#login(java.lang.String, java.util.Map)
+ */
+ public User login(final String appName, final Map loginContext) throws Exception {
+ User user = null;
+
+ final Map objectModel = ContextHelper.getObjectModel( this.context );
+
+ // first check, if we are already logged in
+ if ( this.isLoggedIn(appName) ) {
+ user = ApplicationUtil.getUser(objectModel);
+ } else {
+ final Request req = ObjectModelHelper.getRequest(objectModel);
+ Session session = req.getSession(false);
+
+ final Application app = this.getApplication(appName);
+ LoginInfo info = null;
+ Map loginInfos = null;
+
+ if ( session != null ) {
+ // is the user already logged in on the security handler?
+ loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
+ if ( loginInfos != null
+ && loginInfos.containsKey(app.getSecurityHandler()) ) {
+ info = (LoginInfo)loginInfos.get(app.getSecurityHandler());
+ user = info.user;
+ }
+ }
+ if ( user == null ) {
+ user = app.getSecurityHandler().login(loginContext);
+ if ( user != null ) {
+ // create new login info
+ session = req.getSession();
+ loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
+ if ( loginInfos == null ) {
+ loginInfos = new HashMap();
+ }
+ info = new LoginInfo(user);
+ loginInfos.put(app.getSecurityHandler().getId(), info);
+ }
+ }
+
+ // user can be null, if login failed
+ if ( user != null ) {
+ info.incUsageCounter(appName);
+ session.setAttribute(LOGIN_INFO_KEY, loginInfos);
+
+ // set the user in the session
+ session.setAttribute(USER + '-' + appName, user);
+ objectModel.put(ApplicationManager.USER, user);
+
+ // set the application in the object model
+ objectModel.put(ApplicationManager.APPLICATION, app);
+
+ // notify the application
+ app.userDidLogin(user, loginContext);
+
+ // set the application data in the session
+ Object data = ObjectUtils.NULL;
+ if ( app.getApplicationStore() != null ) {
+ data = app.getApplicationStore().loadApplicationData(user, app);
+ }
+ session.setAttribute(APPLICATION_KEY_PREFIX + appName, data);
+ objectModel.put(ApplicationManager.APPLICATION_DATA, data);
+ // notify application
+ app.userIsAccessing(user);
+ }
+ }
+
+ return user;
+ }
+
+ /**
+ * @see org.apache.cocoon.auth.ApplicationManager#logout(java.lang.String, java.util.Map)
+ */
+ public void logout(final String appName, final Map logoutContext) {
+ final Map objectModel = ContextHelper.getObjectModel( this.context );
+ final Request req = ObjectModelHelper.getRequest(objectModel);
+ final Session session = req.getSession(false);
+ if ( session != null ) {
+ Application app;
+
+ try {
+ app = this.getApplication(appName);
+ } catch (Exception ignore) {
+ throw new CascadingRuntimeException("Unable to get application '"
+ + appName + "'", ignore);
+ }
+
+ // remove application data from session
+ session.removeAttribute(APPLICATION_KEY_PREFIX + appName);
+
+ // remove application from object model
+ if ( app.equals( ApplicationUtil.getApplication(objectModel) ) ) {
+ objectModel.remove(ApplicationManager.APPLICATION);
+ objectModel.remove(ApplicationManager.APPLICATION_DATA);
+ objectModel.remove(ApplicationManager.USER);
+ }
+
+ // remove user
+ session.removeAttribute(USER + '-' + appName);
+
+ // decrement logininfo counter
+ final Map loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
+ if ( loginInfos != null ) {
+ final LoginInfo info = (LoginInfo)loginInfos.get(app.getSecurityHandler().getId());
+ if ( info != null ) {
+ // notify the application
+ app.userWillLogout(info.user, logoutContext);
+
+ info.decUsageCounter(appName);
+ if ( info.isUsed() ) {
+ session.setAttribute(LOGIN_INFO_KEY, loginInfos);
+ } else {
+ // logout from security handler
+ app.getSecurityHandler().logout(logoutContext, info.user);
+ // remove user info
+ loginInfos.remove(app.getSecurityHandler().getId());
+ if ( loginInfos.size() > 0 ) {
+ session.setAttribute(LOGIN_INFO_KEY, loginInfos);
+ } else {
+ session.removeAttribute(LOGIN_INFO_KEY);
+ // the user has left all applications, test the mode:
+ String mode = null;
+ if ( logoutContext != null ) {
+ mode = (String)logoutContext.get(LOGOUT_CONTEXT_MODE_KEY);
+ }
+ if ( mode == null
+ || mode.equals(LOGOUT_MODE_TERMINATE_SESSION_IF_UNUSED) ) {
+ session.invalidate();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Logs the user out of all applications.
+ * This method has not been tested yet.
+ * @param session The corresponding session
+ */
+ public static void logoutFromAllApplications(final HttpSession session) {
+ final Map loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
+ if ( loginInfos != null ) {
+ final StandardApplicationManager appManager =
+ (StandardApplicationManager)session.getServletContext()
+ .getAttribute(StandardApplicationManager.class.getName());
+ final Iterator i = loginInfos.values().iterator();
+ while ( i.hasNext() ) {
+ final LoginInfo info = (LoginInfo)i.next();
+ if ( info.isUsed() ) {
+ final Iterator appIter = info.getApplications().iterator();
+ SecurityHandler handler = null;
+ while ( appIter.hasNext() ) {
+ final String appName = (String)appIter.next();
+ try {
+ final Application app = appManager.getApplication(appName);
+ app.userWillLogout(info.getUser(), null);
+ handler = app.getSecurityHandler();
+ } catch (Exception ignore) {
+ // we ignore this
+ }
+ }
+ handler.logout(null, info.getUser());
+ }
+ }
+ }
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/impl/StandardApplicationManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/impl/StandardApplicationManager.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/PortalApplication.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/PortalApplication.java?rev=414856&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/PortalApplication.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/PortalApplication.java Fri Jun 16 09:29:21 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.apache.cocoon.auth.portal;
+
+import java.util.Map;
+
+import org.apache.cocoon.auth.Application;
+
+/**
+ * The current portal application.
+ *
+ * @version $Id$
+*/
+public interface PortalApplication
+ extends Application {
+
+ /**
+ * Return the configuration for the portal.
+ * @return A map containing the different configuration values as defined
+ * by the profile manager.
+ */
+ Map getPortalConfiguration();
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/PortalApplication.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/PortalApplication.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/StandardPortalApplication.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/StandardPortalApplication.java?rev=414856&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/StandardPortalApplication.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/StandardPortalApplication.java Fri Jun 16 09:29:21 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.apache.cocoon.auth.portal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.portal.PortalService;
+import org.apache.cocoon.auth.StandardApplication;
+import org.apache.cocoon.auth.User;
+
+/**
+ * This is a default implementation for a portal application.
+ *
+ * @version $Id$
+*/
+public class StandardPortalApplication
+ extends StandardApplication
+ implements PortalApplication {
+
+ /** The configuration. */
+ protected Map portalConfig;
+
+ /**
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure(final Configuration conf) throws ConfigurationException {
+ super.configure(conf);
+ final Configuration config = conf.getChild("profiles");
+ final Configuration[] children = config.getChildren();
+ this.portalConfig = new HashMap();
+ if ( children != null ) {
+ for(int i=0; i < children.length; i++) {
+ this.portalConfig.put(children[i].getName(), children[i].getAttribute("uri"));
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.cocoon.auth.portal.PortalApplication#getPortalConfiguration()
+ */
+ public Map getPortalConfiguration() {
+ return this.portalConfig;
+ }
+
+ /**
+ * @see org.apache.cocoon.auth.Application#userDidLogin(org.apache.cocoon.auth.User, java.util.Map)
+ */
+ public void userDidLogin(final User user, final Map context) {
+ super.userDidLogin(user, context);
+ PortalService service = null;
+ try {
+ service = (PortalService)this.manager.lookup(PortalService.ROLE);
+ service.getComponentManager().getProfileManager().login();
+ } catch (ServiceException ce) {
+ throw new RuntimeException("Unable to lookup portal service.", ce);
+ } finally {
+ this.manager.release(service);
+ }
+ }
+
+ /**
+ * @see org.apache.cocoon.auth.Application#userWillLogout(org.apache.cocoon.auth.User, java.util.Map)
+ */
+ public void userWillLogout(final User user, final Map context) {
+ PortalService service = null;
+ try {
+ service = (PortalService)this.manager.lookup(PortalService.ROLE);
+ service.getComponentManager().getProfileManager().logout();
+ } catch (ServiceException ce) {
+ throw new RuntimeException("Unable to lookup portal service.", ce);
+ } finally {
+ this.manager.release(service);
+ }
+ super.userWillLogout(user, context);
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/StandardPortalApplication.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/StandardPortalApplication.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/UserInfoProviderImpl.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/UserInfoProviderImpl.java?rev=414856&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/UserInfoProviderImpl.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/UserInfoProviderImpl.java Fri Jun 16 09:29:21 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.apache.cocoon.auth.portal;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.portal.profile.impl.UserInfo;
+import org.apache.cocoon.portal.profile.impl.UserInfoProvider;
+import org.apache.cocoon.auth.ApplicationUtil;
+import org.apache.cocoon.auth.User;
+
+/**
+ * Get the information about the current user.
+ * This implementation uses CAuth.
+ *
+ * @version $Id$
+ */
+public class UserInfoProviderImpl
+implements UserInfoProvider, Contextualizable {
+
+ /** The component context. */
+ protected Context context;
+
+ /**
+ * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+ */
+ public void contextualize(final Context aContext) throws ContextException {
+ this.context = aContext;
+ }
+
+ /**
+ * @see org.apache.cocoon.portal.profile.impl.UserInfoProvider#getUserInfo(java.lang.String, java.lang.String)
+ */
+ public UserInfo getUserInfo(final String portalName, final String layoutKey)
+ throws Exception {
+ final Map objectModel = ContextHelper.getObjectModel(this.context);
+ final User user = ApplicationUtil.getUser(objectModel);
+
+ final UserInfo info = new PortalUserInfo(portalName, layoutKey, user);
+
+ info.setUserName(user.getId());
+ info.setGroup((String)user.getAttribute("group"));
+ final PortalApplication app =
+ (PortalApplication)ApplicationUtil.getApplication(objectModel);
+ info.setConfigurations(app.getPortalConfiguration());
+
+ return info;
+ }
+
+ /**
+ * The user info for the portal engine.
+ */
+ public static final class PortalUserInfo extends UserInfo {
+
+ /** The CAuth user object. */
+ protected final User user;
+
+ /**
+ * Create a new user info object.
+ * @param portalName The current portal name.
+ * @param layoutKey The layout information.
+ * @param aUser The CAuth user object.
+ */
+ public PortalUserInfo(final String portalName, final String layoutKey, final User aUser) {
+ super(portalName, layoutKey);
+ this.user = aUser;
+ }
+
+ /**
+ * @see org.apache.cocoon.portal.profile.PortalUser#isUserInRole(java.lang.String)
+ */
+ public boolean isUserInRole(final String role) {
+ return user.isUserInRole(role);
+ }
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/UserInfoProviderImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/auth/java/org/apache/cocoon/auth/portal/UserInfoProviderImpl.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/status.xml?rev=414856&r1=414855&r2=414856&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Fri Jun 16 09:29:21 2006
@@ -182,6 +182,9 @@
<release version="@version@" date="@date@">
-->
<release version="2.1.10" date="TBD">
+ <action dev="CZ" type="add">
+ Add the CoWarp contribution by Carsten Ziegeler from the Osoco open source project (http://osoco.sourceforge.net/cowarp/).
+ </action>
<action dev="CZ" type="update">
Deprecate session-fw and authentication-fw block. These blocks will be removed in further releases.
</action>