Merged V3.3 to HEAD

20128: Reverse part of previous build fix that breaks other tests ...
   20129: ALF-202, ALF-1488: Fixed portlets in alfresco.war
      - Stop excluding portlet.xml from alfresco.war
      - Used JSR 286 ResourceURL solution to get upload iframes to work in portlets
      - Removed horrific hacks concerning faces session map resolution in portlets and upload servlet
      - WebClientPortletAuthenticator now dispatches to a helper servlet, AuthenticatorServlet, allowing it to use identical servlet mechanisms to authenticate / sign-on the user
      - Portlet Authenticated user now set consistently in application-scoped attribute, so web client, web script portlets and client portlet share same notion of user ID
      - Application.inPortalServer flag now thread local (and thread safe!)
   20130: Merged BRANCHES/V2.2 to BRANCHES/V3.3
      13819: *RECORD ONLY* ACT-6420 - Office 2003 "Install for all users" - DO NOT MERGE
   20131: Merged BRANCHES/V3.1 to BRANCHES/V3.3
      19600: *RECORD ONLY* ALF-2205 - CLONE: Office Plugin: filename overlaps the plugin UI if longer than 40 characters without spaces
         Merged V3.2 to V3.1 (Adobe)
         17499: ETHREEOH-2322 - Office Plugin: filename overlaps the plugin UI if longer than 40 characters without spaces
         19443: ALF-2131 - Office webscripts: Missing close brace, '}'
   20132: ALF-2749 - temporarily skip couple of -ve checks (for MS SQL Server only)
   20133: Merged BRANCHES/V3.2 to BRANCHES/V3.3
      19550: *RECORD ONLY* ALF-1091 - Only 15 tags displayed in Tags section in Browser pane
   20134: Adding files missed during first commit of Meeting Workspace code
   20135: Merged V3.2 to V3.3
      19814: *RECORD ONLY* Fix for ALF-2322 - discussion topic containing non-ascii characters cannot be saved
      19934: *RECORD ONLY* Fix for ALF-2512 - ability to execute JavaScript via cmd servlet by a non-admin user disabled by default.
             - user script execution privileges can be reactivated if required via web-client-config flag <allow-user-script-execute>
      19935: *RECORD ONLY* Corrected imports for 3.2 compatability
   20136: Merge Dev to V3.3
      20104 : ALF-676 -  imapFolders patch fails if versionable aspect is mandatory on cm:content
   20137: Workaround for ALF-2639: Sharepoint: Share Edit Online uses Share protocol rather than Alfresco protocol to build link
      - Replace "https:" protocol with "http:" when generating "Edit Online" URL
   20138: Merged V3.1 to V3.3
      18204: *RECORD ONLY* Merged DEV/TEMPORARY to 3.1
         17837: ETHREEOH-3801: Creating users via the api does not add them to the user store
      18577: *RECORD ONLY* Fix for ETHREEOH-4117, based on CHK-11154
      19373: *RECORD ONLY* Merged V3.2 to V3.1
         19216: ENH-506 - allow script compilation to be disabled for repository tier. Fix to unreported issue with return aspect array from a ScriptNode.
   20139: Merged V2.2 to V3.3
      18518: *RECORD ONLY* Fix for ETWOTWO-1375
      18522: *RECORD ONLY* Merged DEV-TEMPORARY to V2.2
         18440: TinyMCE HTML Image gets invalid path
         18503: ETWOTWO-1035: Error message when bypassing the 'close' and directly clicking on breadcrumb link after a deployment
         18504: ETWOTWO-1035: Error message when bypassing the 'close' and directly clicking on breadcrumb link after a deployment
      18578: Merged DEV-TEMPORARY to V2.2
         18528: ETWOTWO-1114: Missing 'Required' items are not highlighted in the error when missed
      19094: *RECORD ONLY* Merged V3.1 to V2.2
         14015: Fixes for ETHREEOH-1864 and ETHREEOH-1840
   20140: Remove unwanted @overide
   20141: Lazy schema introspection to shave off a few seconds on startup
      - Saves about 5s on dev machine
      - Hibernate still has to look at the DB metadata, though
   20144: Merged V2.2 to V3.3
      18859: (RECORD ONLY) ALF-1882: Merged V3.2 to V2.2
         17292: ETHREEOH-1842: Ticket association with HttpSession IDs tracked so that we don't invalidate a ticket in use by multiple sessions prematurely
            - AuthenticationService validate, getCurrentTicket, etc. methods now take optional sessionId arguments
      18864: (RECORD ONLY) ALF-1882: Fixed compilation error from previous checkin.
   20145: Merged V3,1 to V3.3
      19584: (RECORD ONLY) ALF-2207: Merged V3.2 to V3.1 (Adobe)
         18277: Merged DEV_TEMPORARY to V3.2
            18178: ETHREEOH-3222: ERROR [org.alfresco.webdav.protocol] WebDAV method not implemented - PROPPATCH
      19660: (RECORD ONLY) ALF-2266: Merged V3.2 to V3.1 (Adobe)
         19562: Merged DEV/BELARUS/V3.2-2010_02_24 to V3.2
            19244: ALF-1816: Email templates can no longer be selected when creating a rule for the action 'Send email to specified users' following an upgrade
               - New patch has been created to create invite email templates and notify email templates folders if those are absent. Also it moves default notify and invite templates into appropriate folders. 
      19662: (RECORD ONLY) Incremented version label
      19663: (RECORD ONLY) Corrected version label
      19779: (RECORD ONLY) Incremented version label
   20148: Merged PATCHES/V3.2.r to V3.3
      20029: ALF-2624: Avoid NPE in LDAP sync when there are dangling references and improve logging
      20053: (RECORD ONLY) Incremented version number
   20151: ALF-2749 - unit test fix (re-arranged -ve checks for txn boundaries, functionally equivalent)
   20152: Merged HEAD to BRANCHES/V3.3: (RECORD ONLY)
      20050: Fix ALF-2637: objectTypeId updatability reported as "readonly" rather then "oncreate"
      20051: Fix for ALF-2609:  CMIS ACL mapping improvements
      20052: Fix for ALF-2609:  CMIS ACL mapping improvements
      20086: Fix re-opened ALF-2637: "objectTypeId" updatability reported as "readonly" rather then "oncreate"
      20125: Fix ALF-2728: AtomPub renditions are not rendered as part of cmis:object, although their rel links are.
   20153: Merged HEAD to BRANCHES/V3.3: (RECORD ONLY)
      20067: Fix ALF-2691: Choice display names in Type Definition are not escaped properly in AtomPub binding
   20154: ALF-1598: Share - Edit online missing on preview page
      - Note: The details page doesn't know when Office opens the file, so may show stale information.
   20156: Build/unit test - comment-out force re-index (IndexCheckServiceImplTest)
   20157: Office add-in: Missing i18n string found whilst investigating ALF-605: Script error appears when start typing not-existent user in "Assign to" filed
      - Changed behaviour slightly so that "start workflow" panel remains if error occurred during submit
   20164: Fix trailing commas that MSIE doesn't like. Plus fix for renamed webscript reference.
   20168: Attempting to fix failing test in ThumbnailService.
      The change adds some extra logging and exception info too.
   20169: Build/unit test - temporarily put back "force re-index" (IndexCheckServiceImplTest)
      - TODO: re-work test for build env
   20170: Fix NPE (AVMStoreImpl.createSnapshot)
      - see DBC-HEADPOSTGRESQL-34
   20173: Propagate IOExceptions from retryable write transactions in AlfrescoDiskDriver
   20176: Merge from V3.2 to V3.3. Merge ok'ed by Steve.
      20175: JMX configuration of enterprise logging broken
   20178: JodConverter loggers are now exposed in JMX.
      This follows on from check-ins 20175 (on V32) and 20176 (on V33) which fixed the JMX logging for enterprise code.
   20180: Fixes ALF-2021 by adding new date format properties and exposing YUI widget options.
   20185: Various core fixes and additional debug output. Part of ALF-1554.
   20186: Fix for OpenOffice multiple versions per edit problem. ALF-1554.
   20187: Merged BRANCHES/DEV/V3.3-BUG-FIX to BRANCHES/V3.3:
      20181: IndexCheckServiceImplTest - by default, check test store only (reduces current ent build time by nearly 1 hour !)
   20188: Fix -exploded build target for Share to copy core classes folder
   20191: Merged HEAD to BRANCHES/V3.3: (RECORD ONLY)
      20190: Fix ALF-2774: Atompub createDocument with versioningState=checkedout followed by checkin does not create major version, Fix ALF-2782: AtomPub binding incorrectly handles atom:title when no value is provided (often done for compliant atom entry)
   20193: Merge 3.2 to 3.3:
      19759: Fix for CIFS/CheckInOut.exe save of working copy breaks lock on original file. ALF-2028. (Record-only)
      19760: Fix for working copy checked out via CIFS is not accessible until FileStateReaper expires file state. ALF-962. (Record-only)
   20195: Form fields for numbers are now rendered much smaller that text fields following feedback from meetups. Must be included in 3.3 as requested by Paul.
   20197: Rules: Size property is now more userfriendly & IE bugs are solved
      - Numbers and booleans where posted as strings to the server making property comparisons against properties such as "Size" to fail on the server
      - Size, encoding & mimetype are now options by default in the "IF/Unless" drop downs
      - When comparing Size properties a "bytes" label is placed to the right of the text field
      - "Show more..." menu now displays aspect/type ids on mouse hover in the tree 
      - "Show more..." menu now displays a new column for the property name in the list next to the property displayLabel
      - The list in the "Show more..." menu now stays in its place instead of being pushed down in some browsers
      - IE css fixes to make rules look good in IE 6, 7 & 8
      - Fixed IE 6 & 7 issue with generateDomId & getAttribute("id") not being in sync
      - Fixed IE 6 & 7 issue where Selector.query only worked with "id" as root attribute
   20199: Merge 3.1 to 3.3 (All record-only):
      14483: Merged HEAD to v3.1:
                 13942 Added FTP IPv6 support. MOB-714.
      14484: Merged HEAD to v3.1:
                 13943 Added FTP IPv6 configuration. Added the ftp.ipv6 property. MOB-714.
      14523: Add trailing 'A' to CIFS server name, removed by recent checkin.
      14916: Fixes for local domain lookup when WINS is configured. ETHREEOH-2263.
      14921: Merge HEAD to V3.1:
                 14599: Fixes to file server ACL parsing, part of ETHREEOH-2177
      14930: Updated svn:mergeinfo
      15231: Fix for cut/paste file between folders on CIFS. ETHREEOH-2323.
      15570: Merge 3.2 to 3.1:
                 15548: CIFS server memory leak fixes (clear auth context, session close). ETHREEOH-2538
      15571: Merge 3.2 to 3.1:
                 15549: Check for null ClientInfo in the setCurrentUser() method and clear the auth context. Part of ETHREEOH-2538.
                 15550: Fixed performance issue in the continue search code, add warn level output of folder search timing.
      15572: Update svn:mergeinfo
      15627: Merge 3.2 to 3.1:
                 15626: Fixed NetBIOS reports an invalid packet during session connection, and connection stalls for a while. JLAN-86.
      15628: Update svn:mergeinfo
      15780: Fix for MS Office document locking issue. ETHREEOH-2579.
      15827: Fixed bug in delete node event processing.
      16160: Minor change to debug output
      16162: Add support for the . and .. pseudo entries in a folder search.
      16163: Added timstamp tracking via the file state cache, blend cached timestamps into file info/folder search results.
      16555: Fix for processing of NetBIOS packets over 64K in the older JNI code. Part of ETHREEOH-2882.
      16556: Fix for CIFS session leak and 100% CPU when connect/disconnecting quickly. ETHREEOH-2881.
      16559: Fix for ACL parsing in the standalone JLAN Server build. JLAN-89.
      16666: Fix for CIFS cannot handle requests over 64K in JNI code, causes session disconnect, standalone server. JLAN-91.
      16709: Fixed the FTP not logged on status return code, now uses reply code 530. JLAN-90.
      16710: Added CIFS NT status code/text for the 'account locked' status, 0xC0000234. ETHREEOH-2897.
      16717: Fixed setAllowConsoleShutdown setting in standalone server can cause infinite loop. JLAN-38.
      16718: Fix for Alfresco and AVM spaces are empty when viewed by FTP and Alfresco is run as non-root. ETHREEOH-2652.
      16727: Fix for unable to connect via FTP via Firefox (when anonymous logons are not enabled). ETHREEOH-2012.
      16987: Merge 2.2 to 3.1:
                 13089: (record-only) Fix "Read-Write transaction" exception, when the user does not exist. ETWOTWO-1055.
                 13091: (record-only) Fix for NFS server "Read-Write transaction started within read-only transaction" exception. ETWOTWO-1054.
                 14190: (record-only) Fix for cut/paste a folder from Alfresco CIFS to local drive loses folder contents. ETWOTWO-1159.
                 14191: (record-only) Additional fix for CIFS 'No more connections' error. ETWOTWO-556
                 14199: (record-only) Fix for NFS problem with Solaris doing an Access check on the share level handle. ETWOTWO-1225.
                 14210: (record-only) Added support for FTP EPRT and EPSV commands, on IPv4 only. ETWOTWO-325.
                 14216: (record-only) Fixed FTP character encoding, ported UTF8 normalizer code from v3.x. ETWOTWO-1151.
                 14229: (record-only) Remove unused import.
                 14655: (record-only) Convert content I/O exceptions to file server exceptions during write and truncate. ETWOTWO-1241.
                 14825: (record-only) Add support for the extended response to the CIFS NTCreateAndX call, back port of ETWOTWO-1232.
                 15869: (record-only) Port of desktop action client side EXE fixes from v3.x. ETWOTWO-1374.
      17130: Fix for cannot delete file via CIFS that has a thumbnail associated with it. ETHREEOH-3143 and ETHREEOH-3115.
      17359: Fix for CIFS/Kerberos/SPNEGO logon problem with Win2008/Win7 client. ETHREEOH-3225.
      17839: Rewrite the rename file logic to handle MS Office file rename patterns. ETHREEOH-1951.
      17842: Missing file from previous checkin.
      17843: Re-use open files for the same session/process id so that writes on each file handle go to the same file. Port of ETWOTWO-1250.
      17861: Merge 2.2 to 3.1:
                 17803: Re-use open files for the same session/process id so that writes on each file handle go to the same file. ETWOTWO-1250. (Record-only)
      18432: Added FTP data port range configuration via <dataPorts>n:n</dataPorts> config value. ETHREEOH-4103.
      18451: Fixed incorrect FTP debug level name.
   20200: Merge PATCHES/V3.2.1 to 3.3:
      20142: Added debug output to dump the restart file name for FindFirst/FindNext folder searches (via the 'Search' debug output level).
   20201: Merge PATCHES/V3.2.1 to 3.3:
      20143: Fix for files being skipped during a long folder listing via CIFS, ALF-2730.
   20202: Update svn:mergeinfo
   20219: Fix for ALF-2791 - correction to changes in rev 20129 so the upload file servlet path is generated for all cases.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@20567 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2010-06-09 13:25:16 +00:00
parent ac519b9bc3
commit b2e7793c54
18 changed files with 455 additions and 380 deletions

View File

@@ -135,6 +135,7 @@ office.result.exception=Action failed due to exception
office.result.create_space.failed=Could not create space office.result.create_space.failed=Could not create space
office.result.create_space.missing_name=Space must have a Name office.result.create_space.missing_name=Space must have a Name
office.result.space_created=New space created office.result.space_created=New space created
office.result.user_not_found=User Not Found
# Miscellaneous # Miscellaneous
office.unit.kb=KB office.unit.kb=KB

View File

@@ -134,6 +134,7 @@ office.result.exception=Action failed due to exception
office.result.create_space.failed=Could not create space office.result.create_space.failed=Could not create space
office.result.create_space.missing_name=Space must have a Name office.result.create_space.missing_name=Space must have a Name
office.result.space_created=Ordner angelegt office.result.space_created=Ordner angelegt
office.result.user_not_found=User Not Found
# Miscellaneous # Miscellaneous
office.unit.kb=KB office.unit.kb=KB

View File

@@ -167,11 +167,7 @@
<!-- Alfresco Web Client Authenticator (Servlet based) --> <!-- Alfresco Web Client Authenticator (Servlet based) -->
<bean id="webscripts.authenticator.webclient" class="org.alfresco.repo.web.scripts.servlet.WebClientAuthenticatorFactory" /> <bean id="webscripts.authenticator.webclient" class="org.alfresco.repo.web.scripts.servlet.WebClientAuthenticatorFactory" />
<bean id="webscripts.authenticator.jsr168.webclient" class="org.alfresco.repo.web.scripts.portlet.WebClientPortletAuthenticatorFactory" lazy-init="true"> <bean id="webscripts.authenticator.jsr168.webclient" class="org.alfresco.repo.web.scripts.portlet.WebClientPortletAuthenticatorFactory" lazy-init="true"/>
<property name="repository" ref="repositoryHelper" />
<property name="authenticationService" ref="AuthenticationService" />
<property name="transactionService" ref="TransactionService" />
</bean>
<bean id="RemoteUserMapper" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory"> <bean id="RemoteUserMapper" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
<property name="applicationContextManager"> <property name="applicationContextManager">

View File

@@ -18,66 +18,30 @@
*/ */
package org.alfresco.repo.web.scripts.portlet; package org.alfresco.repo.web.scripts.portlet;
import java.io.IOException;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.PortletSession; import javax.portlet.PortletSession;
import javax.portlet.RenderRequest; import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse; import javax.portlet.RenderResponse;
import javax.transaction.UserTransaction;
import org.alfresco.repo.SessionUser; import org.alfresco.repo.web.scripts.servlet.AuthenticatorServlet;
import org.alfresco.repo.model.Repository; import org.alfresco.web.app.servlet.AuthenticationStatus;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.bean.repository.User;
import org.springframework.extensions.webscripts.Authenticator; import org.springframework.extensions.webscripts.Authenticator;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.Description.RequiredAuthentication; import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
import org.springframework.extensions.webscripts.portlet.PortletAuthenticatorFactory; import org.springframework.extensions.webscripts.portlet.PortletAuthenticatorFactory;
import org.springframework.extensions.webscripts.portlet.WebScriptPortletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** /**
* Portlet authenticator which synchronizes with the Alfresco Web Client authentication * Portlet authenticator which synchronizes with the Alfresco Web Client authentication
* *
* @author davidc * @author davidc
* @author dward
*/ */
public class WebClientPortletAuthenticatorFactory implements PortletAuthenticatorFactory public class WebClientPortletAuthenticatorFactory implements PortletAuthenticatorFactory
{ {
// Logger
private static final Log logger = LogFactory.getLog(WebClientPortletAuthenticatorFactory.class);
// dependencies
private AuthenticationService authenticationService;
private TransactionService transactionService;
private Repository repository;
/**
* @param authenticationService
*/
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
/**
* @param scriptContext
*/
public void setRepository(Repository repository)
{
this.repository = repository;
}
/**
* @param transactionService
*/
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.web.scripts.portlet.PortletAuthenticatorFactory#create(javax.portlet.RenderRequest, javax.portlet.RenderResponse) * @see org.alfresco.web.scripts.portlet.PortletAuthenticatorFactory#create(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
*/ */
@@ -112,54 +76,23 @@ public class WebClientPortletAuthenticatorFactory implements PortletAuthenticato
public boolean authenticate(RequiredAuthentication required, boolean isGuest) public boolean authenticate(RequiredAuthentication required, boolean isGuest)
{ {
PortletSession session = req.getPortletSession(); PortletSession session = req.getPortletSession();
req.setAttribute(AuthenticatorServlet.ATTR_REQUIRED_AUTH, required);
// first look for the username key in the session - we add this by hand for some portals req.setAttribute(AuthenticatorServlet.ATTR_IS_GUEST, isGuest);
// when the WebScriptPortletRequest is created PortletContext context = session.getPortletContext();
String portalUser = (String)req.getPortletSession().getAttribute(WebScriptPortletRequest.ALFPORTLETUSERNAME); try
if (portalUser == null)
{ {
portalUser = req.getRemoteUser(); context.getNamedDispatcher(AuthenticatorServlet.SERVLET_NAME).include(req, res);
} }
catch (PortletException e)
if (logger.isDebugEnabled())
{ {
logger.debug("JSR-168 Remote user: " + portalUser); throw new WebScriptException("Failed to authenticate", e);
} }
catch (IOException e)
if (isGuest || portalUser == null)
{ {
if (logger.isDebugEnabled()) throw new WebScriptException("Failed to authenticate", e);
logger.debug("Authenticating as Guest");
// authenticate as guest
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getGuestUserName());
if (logger.isDebugEnabled())
logger.debug("Setting Web Client authentication context for guest");
createWebClientUser(session);
removeSessionInvalidated(session);
} }
else AuthenticationStatus status = (AuthenticationStatus) req.getAttribute(AuthenticatorServlet.ATTR_AUTH_STATUS);
{ return !(status == null || status == AuthenticationStatus.Failure);
if (logger.isDebugEnabled())
logger.debug("Authenticating as user " + portalUser);
AuthenticationUtil.setFullyAuthenticatedUser(portalUser);
// determine if Web Client context needs to be updated
User user = getWebClientUser(session);
if (user == null || !portalUser.equals(user.getUserName()))
{
if (logger.isDebugEnabled())
logger.debug("Setting Web Client authentication context for user " + portalUser);
createWebClientUser(session);
removeSessionInvalidated(session);
}
}
return true;
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -167,66 +100,8 @@ public class WebClientPortletAuthenticatorFactory implements PortletAuthenticato
*/ */
public boolean emptyCredentials() public boolean emptyCredentials()
{ {
String portalUser = (String)req.getPortletSession().getAttribute(WebScriptPortletRequest.ALFPORTLETUSERNAME); // Ticket - based authentication not supported
if (portalUser == null) return true;
{
portalUser = req.getRemoteUser();
}
return (portalUser == null);
}
/**
* Helper. Remove Web Client session invalidated flag
*
* @param session
*/
private void removeSessionInvalidated(PortletSession session)
{
session.removeAttribute(AuthenticationHelper.SESSION_INVALIDATED, PortletSession.APPLICATION_SCOPE);
}
/**
* Helper. Create Web Client session user
*
* @param session
*/
private void createWebClientUser(PortletSession session)
{
UserTransaction tx = null;
try
{
// start a txn as this method interacts with public services
tx = transactionService.getUserTransaction();
tx.begin();
NodeRef personRef = repository.getPerson();
User user = new User(authenticationService.getCurrentUserName(), authenticationService.getCurrentTicket(), personRef);
NodeRef homeRef = repository.getUserHome(personRef);
if (homeRef != null)
{
user.setHomeSpaceId(homeRef.getId());
}
session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user, PortletSession.APPLICATION_SCOPE);
tx.commit();
}
catch (Throwable e)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
} }
} }
/**
* Helper. Get Web Client session user
*
* @param session
* @return
*/
private User getWebClientUser(PortletSession session)
{
SessionUser user = (SessionUser)session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER, PortletSession.APPLICATION_SCOPE);
return user instanceof User ? (User)user : null;
}
}
} }

View File

@@ -48,8 +48,15 @@ public class WebScriptRepoPortlet extends WebScriptPortlet
public void processAction(ActionRequest req, ActionResponse res) throws PortletException, PortletSecurityException, IOException public void processAction(ActionRequest req, ActionResponse res) throws PortletException, PortletSecurityException, IOException
{ {
Application.setInPortalServer(true); Application.setInPortalServer(true);
try
{
super.processAction(req, res); super.processAction(req, res);
} }
finally
{
Application.setInPortalServer(false);
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.web.scripts.portlet.WebScriptPortlet#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse) * @see org.alfresco.web.scripts.portlet.WebScriptPortlet#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
@@ -58,7 +65,14 @@ public class WebScriptRepoPortlet extends WebScriptPortlet
public void render(RenderRequest req, RenderResponse res) throws PortletException, PortletSecurityException, IOException public void render(RenderRequest req, RenderResponse res) throws PortletException, PortletSecurityException, IOException
{ {
Application.setInPortalServer(true); Application.setInPortalServer(true);
try
{
super.render(req, res); super.render(req, res);
} }
finally
{
Application.setInPortalServer(false);
}
}
} }

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.app.servlet.AuthenticationStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
/**
* This servlet serves as a useful 'subroutine' for portlets, which using their request dispatcher, can go 'through the
* looking glass' to this servlet and use the standard Alfresco servlet api-based authentication mechanisms.
*
* @author dward
*/
public class AuthenticatorServlet extends HttpServlet
{
public static final String SERVLET_NAME = "authenticatorServlet";
public static final String ATTR_IS_GUEST = "_alf_isGuest";
public static final String ATTR_REQUIRED_AUTH = "_alf_requiredAuth";
public static final String ATTR_AUTH_STATUS = "_alf_authStatus";
private static final long serialVersionUID = 5657140557243797744L;
private static final Log logger = LogFactory.getLog(AuthenticatorServlet.class);
/*
* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
ServletContext context = getServletContext();
boolean isGuest = (Boolean) req.getAttribute(ATTR_IS_GUEST);
RequiredAuthentication required = (RequiredAuthentication) req.getAttribute(ATTR_REQUIRED_AUTH);
AuthenticationStatus status;
if (isGuest && RequiredAuthentication.guest == required)
{
if (logger.isDebugEnabled())
logger.debug("Authenticating as Guest");
status = AuthenticationHelper.authenticate(context, req, res, true);
}
else
{
if (logger.isDebugEnabled())
logger.debug("Authenticating session");
status = AuthenticationHelper.authenticate(context, req, res, false, false);
}
req.setAttribute(ATTR_AUTH_STATUS, status);
}
}

View File

@@ -34,6 +34,7 @@ import javax.servlet.http.HttpSession;
import org.alfresco.repo.importer.ImporterBootstrap; import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.web.app.portlet.AlfrescoFacesPortlet;
import org.alfresco.web.app.servlet.AuthenticationHelper; import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.ErrorBean; import org.alfresco.web.bean.ErrorBean;
@@ -71,7 +72,7 @@ public class Application
public static final String MESSAGE_BUNDLE = "alfresco.messages.webclient"; public static final String MESSAGE_BUNDLE = "alfresco.messages.webclient";
private static boolean inPortalServer = false; private static ThreadLocal<Boolean> inPortalServer = new ThreadLocal<Boolean>();
private static StoreRef repoStoreRef; private static StoreRef repoStoreRef;
private static String rootPath; private static String rootPath;
private static String companyRootId; private static String companyRootId;
@@ -107,7 +108,7 @@ public class Application
*/ */
public static void setInPortalServer(boolean inPortal) public static void setInPortalServer(boolean inPortal)
{ {
inPortalServer = inPortal; inPortalServer.set(inPortal ? Boolean.TRUE : null);
} }
/** /**
@@ -117,7 +118,8 @@ public class Application
*/ */
public static boolean inPortalServer() public static boolean inPortalServer()
{ {
return inPortalServer; Boolean result = inPortalServer.get();
return result == null ? false : result;
} }
/** /**
@@ -263,7 +265,28 @@ public class Application
*/ */
public static User getCurrentUser(FacesContext context) public static User getCurrentUser(FacesContext context)
{ {
return (User)context.getExternalContext().getSessionMap().get(AuthenticationHelper.AUTHENTICATION_USER); if (inPortalServer())
{
User user = (User) AlfrescoFacesPortlet.getPortletSessionAttribute(context,
AuthenticationHelper.AUTHENTICATION_USER, true);
if (user != null)
{
return user;
}
}
return (User) context.getExternalContext().getSessionMap().get(AuthenticationHelper.AUTHENTICATION_USER);
}
public static void setCurrentUser(FacesContext context, User user)
{
if (inPortalServer())
{
AlfrescoFacesPortlet.setPortletSessionAttribute(context, AuthenticationHelper.AUTHENTICATION_USER, user, true);
}
else
{
context.getExternalContext().getSessionMap().put(AuthenticationHelper.AUTHENTICATION_USER, user);
}
} }
/** /**

View File

@@ -157,30 +157,7 @@ public class ContextListener implements ServletContextListener, HttpSessionListe
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("HTTP session destroyed: " + event.getSession().getId()); logger.debug("HTTP session destroyed: " + event.getSession().getId());
String userKey = null; SessionUser user = (SessionUser)event.getSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER);
if (Application.inPortalServer() == false)
{
userKey = AuthenticationHelper.AUTHENTICATION_USER;
}
else
{
// search for the user object in the portlet wrapped session keys
// each vendor uses a different naming scheme so we search by hand
String userKeyPostfix = "?" + AuthenticationHelper.AUTHENTICATION_USER;
Enumeration enumNames = event.getSession().getAttributeNames();
while (enumNames.hasMoreElements())
{
String name = (String)enumNames.nextElement();
if (name.endsWith(userKeyPostfix))
{
userKey = name;
break;
}
}
}
if (userKey != null)
{
SessionUser user = (SessionUser)event.getSession().getAttribute(userKey);
if (user != null) if (user != null)
{ {
// invalidate ticket and clear the Security context for this thread // invalidate ticket and clear the Security context for this thread
@@ -188,8 +165,7 @@ public class ContextListener implements ServletContextListener, HttpSessionListe
AuthenticationService authService = (AuthenticationService)ctx.getBean("authenticationService"); AuthenticationService authService = (AuthenticationService)ctx.getBean("authenticationService");
authService.invalidateTicket(user.getTicket(), event.getSession().getId()); authService.invalidateTicket(user.getTicket(), event.getSession().getId());
authService.clearCurrentSecurityContext(); authService.clearCurrentSecurityContext();
event.getSession().removeAttribute(userKey); event.getSession().removeAttribute(AuthenticationHelper.AUTHENTICATION_USER);
}
} }
} }
} }

View File

@@ -20,6 +20,7 @@ package org.alfresco.web.app.portlet;
import javax.portlet.PortletContext; import javax.portlet.PortletContext;
import javax.portlet.PortletException; import javax.portlet.PortletException;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest; import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse; import javax.portlet.RenderResponse;
@@ -39,7 +40,8 @@ public class AlfrescoDefaultViewSelector implements DefaultViewSelector
*/ */
public String selectViewId(RenderRequest request, RenderResponse response) throws PortletException public String selectViewId(RenderRequest request, RenderResponse response) throws PortletException
{ {
User user = (User)request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER); User user = (User) request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER,
PortletSession.APPLICATION_SCOPE);
if (user != null && user.getUserName().equals(AuthenticationUtil.getGuestUserName())) if (user != null && user.getUserName().equals(AuthenticationUtil.getGuestUserName()))
{ {
return FacesHelper.BROWSE_VIEW_ID; return FacesHelper.BROWSE_VIEW_ID;

View File

@@ -30,13 +30,19 @@ import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.portlet.ActionRequest; import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse; import javax.portlet.ActionResponse;
import javax.portlet.MimeResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException; import javax.portlet.PortletException;
import javax.portlet.PortletRequest; import javax.portlet.PortletRequest;
import javax.portlet.PortletRequestDispatcher; import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession; import javax.portlet.PortletSession;
import javax.portlet.PortletURL; import javax.portlet.PortletURL;
import javax.portlet.RenderRequest; import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse; import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ResourceURL;
import javax.portlet.UnavailableException; import javax.portlet.UnavailableException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
@@ -93,14 +99,13 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
throws PortletException, IOException throws PortletException, IOException
{ {
Application.setInPortalServer(true); Application.setInPortalServer(true);
try
{
// Set the current locale // Set the current locale
I18NUtil.setLocale(getLanguage(request.getPortletSession())); I18NUtil.setLocale(getLanguage(request.getPortletSession()));
boolean isMultipart = PortletFileUpload.isMultipartContent(request); boolean isMultipart = PortletFileUpload.isMultipartContent(request);
try
{
// NOTE: Due to filters not being called within portlets we can not make use // NOTE: Due to filters not being called within portlets we can not make use
// of the MyFaces file upload support, therefore we are using a pure // of the MyFaces file upload support, therefore we are using a pure
// portlet request/action to handle file uploads until there is a // portlet request/action to handle file uploads until there is a
@@ -163,8 +168,9 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
} }
else else
{ {
SessionUser sessionUser = (SessionUser)request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER); SessionUser sessionUser = (SessionUser) request.getPortletSession().getAttribute(
User user = sessionUser instanceof User ? (User)sessionUser : null; AuthenticationHelper.AUTHENTICATION_USER, PortletSession.APPLICATION_SCOPE);
User user = sessionUser instanceof User ? (User) sessionUser : null;
if (user != null) if (user != null)
{ {
// setup the authentication context // setup the authentication context
@@ -199,7 +205,7 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
catch (AuthenticationException authErr) catch (AuthenticationException authErr)
{ {
// remove User object as it's now useless // remove User object as it's now useless
request.getPortletSession().removeAttribute(AuthenticationHelper.AUTHENTICATION_USER); request.getPortletSession().removeAttribute(AuthenticationHelper.AUTHENTICATION_USER, PortletSession.APPLICATION_SCOPE);
} }
} }
else else
@@ -233,7 +239,30 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
} }
} }
} }
finally
{
Application.setInPortalServer(false);
} }
}
/* (non-Javadoc)
* @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
*/
@Override
public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException
{
Application.setInPortalServer(true);
try
{
super.serveResource(request, response);
}
finally
{
Application.setInPortalServer(false);
}
}
/** /**
* @see org.apache.myfaces.portlet.MyFacesGenericPortlet#facesRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse) * @see org.apache.myfaces.portlet.MyFacesGenericPortlet#facesRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
@@ -243,6 +272,8 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
{ {
Application.setInPortalServer(true); Application.setInPortalServer(true);
try
{
// Set the current locale // Set the current locale
I18NUtil.setLocale(getLanguage(request.getPortletSession())); I18NUtil.setLocale(getLanguage(request.getPortletSession()));
@@ -269,7 +300,8 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
String viewId = request.getParameter(VIEW_ID); String viewId = request.getParameter(VIEW_ID);
// keep track of last view id so we can use it as return page from multi-part requests // keep track of last view id so we can use it as return page from multi-part requests
request.getPortletSession().setAttribute(SESSION_LAST_VIEW_ID, viewId); request.getPortletSession().setAttribute(SESSION_LAST_VIEW_ID, viewId);
SessionUser sessionUser = (SessionUser)request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER); SessionUser sessionUser = (SessionUser) request.getPortletSession().getAttribute(
AuthenticationHelper.AUTHENTICATION_USER, PortletSession.APPLICATION_SCOPE);
User user = sessionUser instanceof User ? (User)sessionUser : null; User user = sessionUser instanceof User ? (User)sessionUser : null;
if (user == null && (viewId == null || viewId.equals(getLoginPage()) == false)) if (user == null && (viewId == null || viewId.equals(getLoginPage()) == false))
{ {
@@ -342,7 +374,7 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
logger.debug("Invalid ticket, requesting login page."); logger.debug("Invalid ticket, requesting login page.");
// remove User object as it's now useless // remove User object as it's now useless
request.getPortletSession().removeAttribute(AuthenticationHelper.AUTHENTICATION_USER); session.removeAttribute(AuthenticationHelper.AUTHENTICATION_USER, PortletSession.APPLICATION_SCOPE);
// login page is the default portal page // login page is the default portal page
response.setContentType("text/html"); response.setContentType("text/html");
@@ -376,6 +408,11 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
} }
} }
} }
finally
{
Application.setInPortalServer(false);
}
}
/** /**
* Handles errors that occur during a process action request * Handles errors that occur during a process action request
@@ -409,9 +446,12 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
PortletRequest portletReq = (PortletRequest) request.getAttribute("javax.portlet.request"); PortletRequest portletReq = (PortletRequest) request.getAttribute("javax.portlet.request");
if (portletReq != null) if (portletReq != null)
{ {
PortletSession session = portletReq.getPortletSession(); PortletSession session = portletReq.getPortletSession(false);
if (session != null)
{
return (ErrorBean)session.getAttribute(ErrorBean.ERROR_BEAN_NAME); return (ErrorBean)session.getAttribute(ErrorBean.ERROR_BEAN_NAME);
} }
}
return null; return null;
} }
@@ -456,6 +496,90 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
} }
/**
* Creates a resource URL from the given faces context.
*
* @param context
* the faces context
* @return the resource URL
*/
public static String getResourceURL(FacesContext context, String path)
{
MimeResponse portletResponse = (MimeResponse) context.getExternalContext().getResponse();
ResourceURL resourceURL = portletResponse.createResourceURL();
resourceURL.setResourceID(path);
return resourceURL.toString();
}
/**
* Gets a session attribute.
*
* @param context
* the faces context
* @param attributeName
* the attribute name
* @param shared
* get the attribute from shared (application) scope?
* @return the portlet session attribute
*/
public static Object getPortletSessionAttribute(FacesContext context, String attributeName, boolean shared)
{
Object portletReq = context.getExternalContext().getRequest();
if (portletReq != null && portletReq instanceof PortletRequest)
{
PortletSession session = ((PortletRequest) portletReq).getPortletSession(false);
if (session != null)
{
return session.getAttribute(attributeName, shared ? PortletSession.APPLICATION_SCOPE
: PortletSession.PORTLET_SCOPE);
}
}
return null;
}
/**
* Sets a session attribute.
*
* @param context
* the faces context
* @param attributeName
* the attribute name
* @param value
* the value
* @param shared
* set the attribute with shared (application) scope?
*/
public static void setPortletSessionAttribute(FacesContext context, String attributeName, Object value,
boolean shared)
{
Object portletReq = context.getExternalContext().getRequest();
if (portletReq != null && portletReq instanceof PortletRequest)
{
PortletSession session = ((PortletRequest) portletReq).getPortletSession();
session.setAttribute(attributeName, value, shared ? PortletSession.APPLICATION_SCOPE
: PortletSession.PORTLET_SCOPE);
}
else
{
context.getExternalContext().getSessionMap().put(attributeName, value);
}
}
/**
* Initializes a new faces context using the portlet objects from a 'wrapped' servlet request.
*
* @param request
* the servlet request
* @return the faces context
*/
public static FacesContext getFacesContext(ServletRequest request)
{
PortletRequest portletReq = (PortletRequest) request.getAttribute("javax.portlet.request");
PortletResponse portletRes = (PortletResponse) request.getAttribute("javax.portlet.response");
PortletConfig portletConfig = (PortletConfig) request.getAttribute("javax.portlet.config");
return FacesHelper.getFacesContext(portletReq, portletRes, portletConfig.getPortletContext());
}
/** /**
* Handles errors that occur during a render request * Handles errors that occur during a render request
*/ */
@@ -522,7 +646,7 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
if (user != null) if (user != null)
{ {
// store the User object in the Session - the authentication servlet will then proceed // store the User object in the Session - the authentication servlet will then proceed
session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user); session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user, PortletSession.APPLICATION_SCOPE);
// Set the current locale // Set the current locale
I18NUtil.setLocale(getLanguage(session)); I18NUtil.setLocale(getLanguage(session));

View File

@@ -20,7 +20,6 @@ package org.alfresco.web.app.servlet;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
@@ -45,6 +44,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.app.portlet.AlfrescoFacesPortlet;
import org.alfresco.web.bean.LoginBean; import org.alfresco.web.bean.LoginBean;
import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.repository.User;
import org.alfresco.web.bean.users.UserPreferencesBean; import org.alfresco.web.bean.users.UserPreferencesBean;
@@ -105,7 +105,8 @@ public final class AuthenticationHelper
public static void setupThread(ServletContext sc, HttpServletRequest req, HttpServletResponse res) public static void setupThread(ServletContext sc, HttpServletRequest req, HttpServletResponse res)
{ {
// setup faces context // setup faces context
FacesContext fc = FacesHelper.getFacesContext(req, res, sc); FacesContext fc = Application.inPortalServer() ? AlfrescoFacesPortlet.getFacesContext(req) : FacesHelper
.getFacesContext(req, res, sc);
// Set the current locale and language // Set the current locale and language
if (Application.getClientConfig(fc).isLanguageSelect()) if (Application.getClientConfig(fc).isLanguageSelect())
@@ -437,7 +438,6 @@ public final class AuthenticationHelper
* The HTTP response * The HTTP response
* @return The User object representing the current user or null if it could not be found * @return The User object representing the current user or null if it could not be found
*/ */
@SuppressWarnings("unchecked")
public static User getUser(final ServletContext sc, final HttpServletRequest httpRequest, HttpServletResponse httpResponse) public static User getUser(final ServletContext sc, final HttpServletRequest httpRequest, HttpServletResponse httpResponse)
{ {
String userId = null; String userId = null;
@@ -454,32 +454,11 @@ public final class AuthenticationHelper
User user = null; User user = null;
// examine the appropriate session to try and find the User object // examine the appropriate session to try and find the User object
SessionUser sessionUser = null; SessionUser sessionUser = Application.getCurrentUser(session);
String sessionUserAttrib = null;
if (Application.inPortalServer() == false)
{
sessionUserAttrib = AUTHENTICATION_USER;
}
else
{
// naff solution as we need to enumerate all session keys until we find the one that
// should match our User objects - this is weak but we don't know how the underlying
// Portal vendor has decided to encode the objects in the session
Enumeration<String> enumNames = (Enumeration<String>) session.getAttributeNames();
while (enumNames.hasMoreElements())
{
String name = enumNames.nextElement();
if (name.endsWith(AUTHENTICATION_USER))
{
sessionUserAttrib = name;
break;
}
}
}
// Make sure the ticket is valid, the person exists, and the cached user is of the right type (WebDAV users have // Make sure the ticket is valid, the person exists, and the cached user is of the right type (WebDAV users have
// been known to leak in but shouldn't now) // been known to leak in but shouldn't now)
if (sessionUserAttrib != null && (sessionUser = (SessionUser) session.getAttribute(sessionUserAttrib)) != null) if (sessionUser != null)
{ {
AuthenticationService auth = (AuthenticationService) wc.getBean(AUTHENTICATION_SERVICE); AuthenticationService auth = (AuthenticationService) wc.getBean(AUTHENTICATION_SERVICE);
try try
@@ -497,7 +476,7 @@ public final class AuthenticationHelper
} }
catch (AuthenticationException authErr) catch (AuthenticationException authErr)
{ {
session.removeAttribute(sessionUserAttrib); session.removeAttribute(AUTHENTICATION_USER);
if (!Application.inPortalServer()) if (!Application.inPortalServer())
{ {
session.invalidate(); session.invalidate();
@@ -511,7 +490,7 @@ public final class AuthenticationHelper
// We have a previously-cached user with the wrong identity - replace them // We have a previously-cached user with the wrong identity - replace them
if (user != null && !user.getUserName().equals(userId)) if (user != null && !user.getUserName().equals(userId))
{ {
session.removeAttribute(sessionUserAttrib); session.removeAttribute(AUTHENTICATION_USER);
if (!Application.inPortalServer()) if (!Application.inPortalServer())
{ {
session.invalidate(); session.invalidate();

View File

@@ -20,16 +20,16 @@ package org.alfresco.web.app.servlet;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.extensions.config.ConfigService;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
@@ -45,6 +45,7 @@ import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.config.ConfigService;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
@@ -77,6 +78,7 @@ public class UploadFileServlet extends BaseServlet
/** /**
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/ */
@SuppressWarnings("unchecked")
protected void service(HttpServletRequest request, HttpServletResponse response) protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException throws ServletException, IOException
{ {
@@ -102,7 +104,8 @@ public class UploadFileServlet extends BaseServlet
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Uploading servlet servicing..."); logger.debug("Uploading servlet servicing...");
HttpSession session = request.getSession(); FacesContext context = FacesContext.getCurrentInstance();
Map<Object, Object> session = context.getExternalContext().getSessionMap();
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
// ensure that the encoding is handled correctly // ensure that the encoding is handled correctly
@@ -162,29 +165,7 @@ public class UploadFileServlet extends BaseServlet
} }
} }
// examine the appropriate session to try and find the User object session.put(FileUploadBean.getKey(uploadId), bean);
if (Application.inPortalServer() == false)
{
session.setAttribute(FileUploadBean.getKey(uploadId), bean);
}
else
{
// naff solution as we need to enumerate all session keys until we find the one that
// should match our User objects - this is weak but we don't know how the underlying
// Portal vendor has decided to encode the objects in the session
Enumeration enumNames = session.getAttributeNames();
while (enumNames.hasMoreElements())
{
String name = (String)enumNames.nextElement();
// find an Alfresco value we know must be there...
if (name.startsWith("javax.portlet.p") && name.endsWith(AuthenticationHelper.AUTHENTICATION_USER))
{
String key = name.substring(0, name.lastIndexOf(AuthenticationHelper.AUTHENTICATION_USER));
session.setAttribute(key + FileUploadBean.getKey(uploadId), bean);
break;
}
}
}
if (bean.getFile() == null && uploadId != null && logger.isWarnEnabled()) if (bean.getFile() == null && uploadId != null && logger.isWarnEnabled())
{ {

View File

@@ -321,7 +321,7 @@ public class LoginBean implements Serializable
// put the User object in the Session - the authentication servlet will then allow // put the User object in the Session - the authentication servlet will then allow
// the app to continue without redirecting to the login page // the app to continue without redirecting to the login page
session.put(AuthenticationHelper.AUTHENTICATION_USER, user); Application.setCurrentUser(fc, user);
// if a redirect URL has been provided then use that // if a redirect URL has been provided then use that
// this allows servlets etc. to provide a URL to return too after a successful login // this allows servlets etc. to provide a URL to return too after a successful login
@@ -427,7 +427,7 @@ public class LoginBean implements Serializable
else else
{ {
Map session = context.getExternalContext().getSessionMap(); Map session = context.getExternalContext().getSessionMap();
SessionUser user = (SessionUser)session.get(AuthenticationHelper.AUTHENTICATION_USER); SessionUser user = Application.getCurrentUser(context);
if (user != null) if (user != null)
{ {
// invalidate ticket and clear the Security context for this thread // invalidate ticket and clear the Security context for this thread

View File

@@ -25,6 +25,9 @@ import javax.faces.component.UIInput;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter; import javax.faces.context.ResponseWriter;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.portlet.AlfrescoFacesPortlet;
public class UploadInput extends UIInput implements NamingContainer public class UploadInput extends UIInput implements NamingContainer
{ {
private static final long serialVersionUID = 4064734856565167835L; private static final long serialVersionUID = 4064734856565167835L;
@@ -34,16 +37,18 @@ public class UploadInput extends UIInput implements NamingContainer
public void encodeBegin(FacesContext context) throws IOException public void encodeBegin(FacesContext context) throws IOException
{ {
ResponseWriter writer = context.getResponseWriter(); ResponseWriter writer = context.getResponseWriter();
String path = context.getExternalContext().getRequestContextPath(); String contextPath = context.getExternalContext().getRequestContextPath();
String path = Application.inPortalServer() ? AlfrescoFacesPortlet.getResourceURL(context, "/uploadFileServlet")
: contextPath + "/uploadFileServlet";
writer.write("<script type='text/javascript' src='"); writer.write("<script type='text/javascript' src='");
writer.write(path); writer.write(contextPath);
writer.write("/scripts/upload_helper.js'></script>\n"); writer.write("/scripts/upload_helper.js'></script>\n");
writer.write("<script type='text/javascript'>"); writer.write("<script type='text/javascript'>");
writer.write("function handle_upload(target)\n"); writer.write("function handle_upload(target)\n");
writer.write("{\n"); writer.write("{\n");
writer.write("handle_upload_helper(target, '', upload_complete, '"+path+"')\n"); writer.write("handle_upload_helper(target, '', upload_complete, '"+path+"', '')\n");
writer.write("}\n"); writer.write("}\n");
writer.write("function upload_complete(id, path, filename)\n"); writer.write("function upload_complete(id, path, filename)\n");

View File

@@ -471,6 +471,11 @@
</init-param> </init-param>
</servlet> </servlet>
<servlet>
<servlet-name>authenticatorServlet</servlet-name>
<servlet-class>org.alfresco.repo.web.scripts.servlet.AuthenticatorServlet</servlet-class>
</servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>Faces Servlet</servlet-name> <servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern> <url-pattern>/faces/*</url-pattern>

View File

@@ -1034,6 +1034,10 @@ alfresco.xforms.RichTextEditor = alfresco.xforms.Widget.extend({
? tinyMCE.get(this.widget.id).getContent() ? tinyMCE.get(this.widget.id).getContent()
: this.widget.innerHTML); : this.widget.innerHTML);
result = result.replace(new RegExp(alfresco.constants.AVM_WEBAPP_URL, "g"), ""); result = result.replace(new RegExp(alfresco.constants.AVM_WEBAPP_URL, "g"), "");
if (result.length == 0)
{
result = null;
}
return result; return result;
}, },

View File

@@ -243,9 +243,11 @@ var OfficeMyTasks =
onComplete: function(textResponse, xmlResponse) onComplete: function(textResponse, xmlResponse)
{ {
// Remove any trailing hash // Remove any trailing hash
var href = window.location.href.replace("#", ""); var href = window.location.href.replace("#", ""),
success = Json.evaluate(textResponse).statusCode;
// Remove any previous "st", "w" or "wd" parameters // Remove any previous "st", "w" or "wd" parameters
href = OfficeAddin.removeParameters(href, "st|w|wd"); href = OfficeAddin.removeParameters(href, success ? "st|w|wd" : "st");
// Optionally add a status string // Optionally add a status string
if (textResponse !== "") if (textResponse !== "")
{ {

View File

@@ -30,8 +30,15 @@ function handle_upload_helper(fileInputElement,
form.encoding = "multipart/form-data"; form.encoding = "multipart/form-data";
form.enctype = "multipart/form-data"; form.enctype = "multipart/form-data";
form.target = iframe.name; form.target = iframe.name;
actionUrl = actionUrl || "/uploadFileServlet"; if (actionUrl != undefined && actionUrl != null)
form.action = contextPath + actionUrl; {
actionUrl = contextPath + actionUrl;
}
else
{
actionUrl = contextPath + "/uploadFileServlet"
}
form.action = actionUrl;
form.appendChild(fileInputElement); form.appendChild(fileInputElement);
var id = d.createElement("input"); var id = d.createElement("input");