Introduce RAP anonymous
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 18 Feb 2012 18:43:50 +0000 (18:43 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 18 Feb 2012 18:43:50 +0000 (18:43 +0000)
Improve RAP UI (add user menu in toolbar, remove standard menus)
Introduce user home perspective

git-svn-id: https://svn.argeo.org/commons/trunk@5100 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

34 files changed:
security/plugins/org.argeo.security.equinox/META-INF/spring/loginModules.xml
security/plugins/org.argeo.security.equinox/plugin.xml
security/plugins/org.argeo.security.equinox/security.properties [new file with mode: 0644]
security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java
security/plugins/org.argeo.security.ui.rap/META-INF/jaas_default.txt
security/plugins/org.argeo.security.ui.rap/META-INF/spring/commands.xml [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/META-INF/spring/osgi.xml [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/branding/public.html [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/build.properties
security/plugins/org.argeo.security.ui.rap/icons/closeAll.gif [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/icons/exit.png [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/icons/home.gif [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/icons/main.gif [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/icons/password.gif [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/icons/preferences.png [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/plugin.xml
security/plugins/org.argeo.security.ui.rap/pom.xml
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/AnonymousEntryPoint.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapActionBarAdvisor.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapSecureWorkbenchWindowAdvisor.java [deleted file]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapWindowAdvisor.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapWorkbenchAdvisor.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java [deleted file]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureEntryPoint.java
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureRapActivator.java
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureWorkbenchAdvisor.java [deleted file]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureWorkbenchWindowAdvisor.java [deleted file]
security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/commands/UserMenu.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui/icons/home.gif [new file with mode: 0644]
security/plugins/org.argeo.security.ui/icons/user.gif [new file with mode: 0644]
security/plugins/org.argeo.security.ui/plugin.xml
security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/UserHomePerspective.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/views/UserProfile.java [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java

index fe7bb602d39999fd9dd726d572e9fe18d5cbdbb9..ed0a7886085862471ae9f89d75e9c4368ab5bdfa 100644 (file)
@@ -4,6 +4,14 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
 
+       <bean
+               class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+               <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
+               <property name="locations">
+                       <value>osgibundle:security.properties</value>
+               </property>
+       </bean>
+
        <bean id="springLoginModule" class="org.argeo.security.equinox.SpringLoginModule"
                scope="prototype">
                <property name="authenticationManager" ref="authenticationManager" />
                <property name="authenticationManager" ref="authenticationManager" />
        </bean>
 
+       <bean id="anonymousSpringLoginModule" class="org.argeo.security.equinox.SpringLoginModule"
+               scope="prototype">
+               <property name="anonymous" value="true" />
+               <property name="anonymousRole" value="${argeo.security.anonymousRole}" />
+               <property name="key" value="${argeo.security.systemKey}" />
+               <property name="authenticationManager" ref="authenticationManager" />
+       </bean>
+
        <bean id="osSpringLoginModule" class="org.argeo.security.equinox.OsSpringLoginModule"
                scope="prototype">
                <property name="authenticationManager" ref="authenticationManager" />
index 4032022dcb2147cf2c5a93055609c02d938cc77a..2cc81f13744dea95eed5bbbf803e1736f1549159 100644 (file)
@@ -3,15 +3,19 @@
 <plugin>
   <!-- Argeo -->
   <extension id="springLoginModule" name="Argeo Spring" point="org.eclipse.equinox.security.loginModule">
-  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Argeo Spring Login Module"/>
+  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Username/password authentication"/>
   </extension>
 
-  <extension id="springLoginModuleRemote" name="Argeo Spring" point="org.eclipse.equinox.security.loginModule">
-  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Argeo Spring Login Module"/>
+  <extension id="springLoginModuleRemote" name="Argeo Spring Remote" point="org.eclipse.equinox.security.loginModule">
+  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Delegates authentication to a remote URL (typically JCR)"/>
+  </extension>
+
+  <extension id="anonymousSpringLoginModule" name="Argeo Spring Anonymous" point="org.eclipse.equinox.security.loginModule">
+  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Public access without authentication"/>
   </extension>
 
   <extension id="osSpringLoginModule" name="Argeo Spring OS" point="org.eclipse.equinox.security.loginModule">
-  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Argeo Spring OS Login Module"/>
+  <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Use the operating system authentication of the JVM"/>
   </extension>
   
   <!-- Java -->
diff --git a/security/plugins/org.argeo.security.equinox/security.properties b/security/plugins/org.argeo.security.equinox/security.properties
new file mode 100644 (file)
index 0000000..219b1c7
--- /dev/null
@@ -0,0 +1,3 @@
+argeo.security.systemKey=argeo
+
+argeo.security.anonymousRole=ROLE_ANONYMOUS
index 71ce5715bc937f5d6a4d310d913aa24af8c3da71..4d0cb6de65aaeb9124f766c4c213f97a15996c66 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.security.equinox;
 
 import java.util.Map;
+import java.util.UUID;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
@@ -15,7 +16,10 @@ import org.argeo.security.NodeAuthenticationToken;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationManager;
 import org.springframework.security.BadCredentialsException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
 import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
 import org.springframework.security.providers.jaas.SecurityContextLoginModule;
 
 /** Login module which caches one subject per thread. */
@@ -33,6 +37,10 @@ public class SpringLoginModule extends SecurityContextLoginModule {
        private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
 
        private Boolean remote = false;
+       private Boolean anonymous = false;
+
+       private String key = null;
+       private String anonymousRole = "ROLE_ANONYMOUS";
 
        public SpringLoginModule() {
 
@@ -52,6 +60,10 @@ public class SpringLoginModule extends SecurityContextLoginModule {
                        if (SecurityContextHolder.getContext().getAuthentication() != null)
                                return super.login();
 
+                       if (remote && anonymous)
+                               throw new LoginException(
+                                               "Cannot have a Spring login module which is remote and anonymous");
+
                        // reset all principals and credentials
                        if (log.isTraceEnabled())
                                log.trace("Resetting all principals and credentials of "
@@ -63,6 +75,20 @@ public class SpringLoginModule extends SecurityContextLoginModule {
                        if (subject.getPublicCredentials() != null)
                                subject.getPublicCredentials().clear();
 
+                       // deals first with public access since it's simple
+                       if (anonymous) {
+                               // TODO integrate with JCR?
+                               Object principal = UUID.randomUUID().toString();
+                               GrantedAuthority[] authorities = { new GrantedAuthorityImpl(
+                                               anonymousRole) };
+                               AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
+                                               key, principal, authorities);
+                               Authentication auth = authenticationManager
+                                               .authenticate(anonymousToken);
+                               registerAuthentication(auth);
+                               return super.login();
+                       }
+
                        if (callbackHandler == null)
                                throw new LoginException("No call back handler available");
 
@@ -154,7 +180,26 @@ public class SpringLoginModule extends SecurityContextLoginModule {
                this.authenticationManager = authenticationManager;
        }
 
+       /** Authenticates on a remote node */
        public void setRemote(Boolean remote) {
                this.remote = remote;
        }
+
+       /**
+        * Request anonymous authentication (incompatible with remote)
+        */
+       public void setAnonymous(Boolean anonymous) {
+               this.anonymous = anonymous;
+       }
+
+       /** Role identifying an anonymous user */
+       public void setAnonymousRole(String anonymousRole) {
+               this.anonymousRole = anonymousRole;
+       }
+
+       /** System key */
+       public void setKey(String key) {
+               this.key = key;
+       }
+
 }
index 72b66eabfa0044d5293d50d1263efdd6c1f1f897..3829f93bb6087b7bcc02eca0c73b45cbc478976c 100644 (file)
@@ -8,6 +8,11 @@ SPRING {
         extensionId="org.argeo.security.equinox.springLoginModule";
 };
 
+SPRING_ANONYMOUS {
+    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
+        extensionId="org.argeo.security.equinox.anonymousSpringLoginModule";
+};
+
 SPRING_SECURITY_CONTEXT {
     org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
         extensionId="org.argeo.security.equinox.springSecurityContextLoginModule";
diff --git a/security/plugins/org.argeo.security.ui.rap/META-INF/spring/commands.xml b/security/plugins/org.argeo.security.ui.rap/META-INF/spring/commands.xml
new file mode 100644 (file)
index 0000000..1dc8d53
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <bean id="openChangePasswordDialog" class="org.argeo.security.ui.commands.OpenChangePasswordDialog"
+               scope="prototype">
+               <property name="userDetailsManager" ref="userDetailsManager" />
+       </bean>
+</beans>
diff --git a/security/plugins/org.argeo.security.ui.rap/META-INF/spring/osgi.xml b/security/plugins/org.argeo.security.ui.rap/META-INF/spring/osgi.xml
new file mode 100644 (file)
index 0000000..9e357a3
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+       xmlns:osgi="http://www.springframework.org/schema/osgi"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/osgi  \r
+       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+       http://www.springframework.org/schema/beans   \r
+       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
+       osgi:default-timeout="30000">\r
+\r
+       <reference id="userDetailsManager"\r
+               interface="org.springframework.security.userdetails.UserDetailsManager"\r
+               cardinality="0..1" />\r
+</beans:beans>
\ No newline at end of file
diff --git a/security/plugins/org.argeo.security.ui.rap/branding/public.html b/security/plugins/org.argeo.security.ui.rap/branding/public.html
new file mode 100644 (file)
index 0000000..e50f6e9
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+<head></head>
+<body>
+<center>
+<table height="100%">
+<tr>
+       <td style="vertical-align:middle">
+               <a 
+                       style="font-family:sans-serif;color:#0066CC;text-decoration:none;" 
+                       href="javascript:location.reload(true);" 
+                       title="Refresh"
+               >Refresh...</a>
+       </td>
+</tr>
+</table>
+</center>
+</body>
+</html>
\ No newline at end of file
index 572b0b491b6a4d30fb460fb57c682334a4704beb..5618fae36d54dc2947d5f94aad2c5030a989ade1 100644 (file)
@@ -1,5 +1,6 @@
 bin.includes = plugin.xml,\
                META-INF/,\
-               branding/
+               branding/,\
+               icons/
 source.. = src/main/java/
 output.. = target/classes/
diff --git a/security/plugins/org.argeo.security.ui.rap/icons/closeAll.gif b/security/plugins/org.argeo.security.ui.rap/icons/closeAll.gif
new file mode 100644 (file)
index 0000000..28a3785
Binary files /dev/null and b/security/plugins/org.argeo.security.ui.rap/icons/closeAll.gif differ
diff --git a/security/plugins/org.argeo.security.ui.rap/icons/exit.png b/security/plugins/org.argeo.security.ui.rap/icons/exit.png
new file mode 100644 (file)
index 0000000..cfbf9d1
Binary files /dev/null and b/security/plugins/org.argeo.security.ui.rap/icons/exit.png differ
diff --git a/security/plugins/org.argeo.security.ui.rap/icons/home.gif b/security/plugins/org.argeo.security.ui.rap/icons/home.gif
new file mode 100644 (file)
index 0000000..fd0c669
Binary files /dev/null and b/security/plugins/org.argeo.security.ui.rap/icons/home.gif differ
diff --git a/security/plugins/org.argeo.security.ui.rap/icons/main.gif b/security/plugins/org.argeo.security.ui.rap/icons/main.gif
new file mode 100644 (file)
index 0000000..90a0014
Binary files /dev/null and b/security/plugins/org.argeo.security.ui.rap/icons/main.gif differ
diff --git a/security/plugins/org.argeo.security.ui.rap/icons/password.gif b/security/plugins/org.argeo.security.ui.rap/icons/password.gif
new file mode 100644 (file)
index 0000000..a6b251f
Binary files /dev/null and b/security/plugins/org.argeo.security.ui.rap/icons/password.gif differ
diff --git a/security/plugins/org.argeo.security.ui.rap/icons/preferences.png b/security/plugins/org.argeo.security.ui.rap/icons/preferences.png
new file mode 100644 (file)
index 0000000..aa0dc0b
Binary files /dev/null and b/security/plugins/org.argeo.security.ui.rap/icons/preferences.png differ
index d9afe3e2b0090d6d5802c677e15ccc447457d160..cf2222a9f47c1f9d655fdfe898d543b32f59dd93 100644 (file)
@@ -4,10 +4,15 @@
    <extension
          point="org.eclipse.rap.ui.entrypoint">
       <entrypoint
-            class="org.argeo.security.ui.rap.SecureEntryPoint"
             id="org.argeo.security.ui.rap.secureEntryPoint"
+            class="org.argeo.security.ui.rap.SecureEntryPoint"
             parameter="secureWebUi">
       </entrypoint>
+      <entrypoint
+            id="org.argeo.security.ui.rap.anonymousEntryPoint"
+            class="org.argeo.security.ui.rap.AnonymousEntryPoint"
+            parameter="publicWebUi">
+      </entrypoint>
    </extension>
 
        <extension
             defaultEntrypointId="org.argeo.security.ui.rap.secureEntryPoint"
             title="Argeo Web UI"
             favicon="branding/favicon.ico"
-            body="branding/default.htm">
+            body="branding/public.html">
+       </branding>
+       <branding
+                       id="org.argeo.security.ui.rap.branding"
+            servletName="public"
+            defaultEntrypointId="org.argeo.security.ui.rap.anonymousEntryPoint"
+            title="Argeo Public Web UI"
+            favicon="branding/favicon.ico"
+            body="branding/public.html">
        </branding>
        </extension>
 
       </callbackHandlerMapping>
    </extension>
 
+  <extension point="org.eclipse.ui.menus">
+     <menuContribution locationURI="toolbar:org.eclipse.ui.main.toolbar">
+        <toolbar id="org.argeo.security.ui.rap.userToolbar">
+           <command
+                 commandId="org.argeo.security.ui.rap.mainMenuCommand"
+                 icon="icons/main.gif"
+                 id="org.argeo.security.ui.rap.mainMenu"
+                 style="pulldown">
+           </command>
+           <command commandId="org.eclipse.ui.file.save"/>
+           <command commandId="org.eclipse.ui.file.saveAll"/>
+        </toolbar>
+     </menuContribution>
+     <menuContribution locationURI="menu:org.argeo.security.ui.rap.mainMenu">
+        <command
+              commandId="org.argeo.security.ui.rap.userMenuCommand"
+              icon="icons/home.gif"
+              id="org.argeo.security.ui.rap.userMenu">
+        </command>
+        <command
+              commandId="org.eclipse.ui.window.preferences"
+              icon="icons/preferences.png"/>
+        <command
+              commandId="org.argeo.security.ui.rap.openChangePasswordDialog"
+              icon="icons/password.gif"
+              label="Change password"/>
+        <separator
+              name="org.argeo.security.ui.rap.beforeFile"
+              visible="true">
+        </separator>
+        <command
+              commandId="org.eclipse.ui.file.closeAll"
+              icon="icons/closeAll.gif"/>
+           <command commandId="org.eclipse.ui.file.save"/>
+           <command commandId="org.eclipse.ui.file.saveAll"/>
+        <separator
+              name="org.argeo.security.ui.rap.beforeExit"
+              visible="true">
+        </separator>
+        <!--<command commandId="org.eclipse.ui.views.showView"/>-->
+        <!--<command commandId="org.eclipse.ui.perspectives.showPerspective"/>-->
+        <command
+              commandId="org.eclipse.ui.file.exit"
+              icon="icons/exit.png"/>
+     </menuContribution>
+  </extension>
+
+   <extension point="org.eclipse.ui.commands">
+      <command
+            id="org.argeo.security.ui.rap.openChangePasswordDialog"
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            name="Change Password">
+      </command>
+      <command
+            id="org.argeo.security.ui.rap.mainMenuCommand"
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            name="Main">
+      </command>
+    </extension>
+    
+  <extension
+           point="org.eclipse.ui.activities">
+        <activity
+              description="Not anonymous"
+              id="org.argeo.security.ui.rap.notAnonymousActivity"
+              name="NotAnonymous">
+                 <enabledWhen>
+                       <not>
+                   <with variable="roles">
+                     <iterate ifEmpty="false" operator="or">
+                       <equals value="ROLE_ANONYMOUS" />
+                     </iterate>
+                   </with>
+                   </not>
+                 </enabledWhen>
+        </activity>
+        <activityPatternBinding
+              activityId="org.argeo.security.ui.rap.notAnonymousActivity"
+              pattern="org.argeo.security.ui.rap/org.argeo.security.ui.rap.userMenuCommand"/>
+        <activityPatternBinding
+              activityId="org.argeo.security.ui.rap.notAnonymousActivity"
+              pattern="org.argeo.security.ui.rap/org.eclipse.ui.window.preferences"/>
+        <activityPatternBinding
+              activityId="org.argeo.security.ui.rap.notAnonymousActivity"
+              pattern="org.argeo.security.ui.rap/org.argeo.security.ui.rap.openChangePasswordDialog"/>
+     </extension>
 </plugin>
index cfd6121cbec001a41294db04bb3d574f70d18016..633a95297abd8201bbe09e09efd9be9a9ee54b26 100644 (file)
@@ -31,7 +31,7 @@
                                                <Bundle-Activator>org.argeo.security.ui.rap.SecureRapActivator</Bundle-Activator>
                                                <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
                                                <Require-Bundle>org.eclipse.rap.ui,org.eclipse.core.runtime</Require-Bundle>
-                                               <Import-Package>org.springframework.core,*</Import-Package>
+                                               <Import-Package>org.springframework.core,org.argeo.eclipse.spring,*</Import-Package>
                                        </instructions>
                                </configuration>
                        </plugin>
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/AnonymousEntryPoint.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/AnonymousEntryPoint.java
new file mode 100644 (file)
index 0000000..aad267c
--- /dev/null
@@ -0,0 +1,103 @@
+package org.argeo.security.ui.rap;
+
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.rwt.RWT;
+import org.eclipse.rwt.lifecycle.IEntryPoint;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * RAP entry point which authenticates the subject as anonymous, for public
+ * unauthenticated access.
+ */
+public class AnonymousEntryPoint implements IEntryPoint {
+       private final static Log log = LogFactory.getLog(AnonymousEntryPoint.class);
+
+       /**
+        * How many seconds to wait before invalidating the session if the user has
+        * not yet logged in.
+        */
+       private Integer loginTimeout = 1 * 60;
+       private Integer sessionTimeout = 15 * 60;
+
+       @Override
+       public int createUI() {
+               // Short login timeout so that the modal dialog login doesn't hang
+               // around too long
+               RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
+
+               if (log.isDebugEnabled())
+                       log.debug("Anonymous THREAD=" + Thread.currentThread().getId()
+                                       + ", sessionStore=" + RWT.getSessionStore().getId());
+
+               // create display
+               final Display display = PlatformUI.createDisplay();
+
+               // log in
+               final ILoginContext loginContext = SecureRapActivator
+                               .createLoginContext(SecureRapActivator.CONTEXT_SPRING_ANONYMOUS);
+               Subject subject = null;
+               try {
+                       loginContext.login();
+                       subject = loginContext.getSubject();
+               } catch (LoginException e) {
+                       throw new ArgeoException(
+                                       "Unexpected exception during authentication", e);
+               }
+
+               // identify after successful login
+               if (log.isDebugEnabled())
+                       log.debug("Authenticated " + subject);
+               final String username = subject.getPrincipals().iterator().next()
+                               .getName();
+
+               // Once the user is logged in, she can have a longer session timeout
+               RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
+
+               // Logout callback when the display is disposed
+               display.disposeExec(new Runnable() {
+                       public void run() {
+                               log.debug("Display disposed");
+                               logout(loginContext, username);
+                       }
+               });
+
+               //
+               // RUN THE WORKBENCH
+               //
+               Integer returnCode = null;
+               try {
+                       returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
+                               public Integer run() {
+                                       RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor(
+                                                       null);
+                                       int result = PlatformUI.createAndRunWorkbench(display,
+                                                       workbenchAdvisor);
+                                       return new Integer(result);
+                               }
+                       });
+                       logout(loginContext, username);
+               } finally {
+                       display.dispose();
+               }
+               return returnCode;
+       }
+
+       private void logout(ILoginContext secureContext, String username) {
+               try {
+                       secureContext.logout();
+                       log.info("Logged out " + (username != null ? username : "")
+                                       + " (THREAD=" + Thread.currentThread().getId() + ")");
+               } catch (LoginException e) {
+                       log.error("Erorr when logging out", e);
+               }
+       }
+}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapActionBarAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapActionBarAdvisor.java
new file mode 100644 (file)
index 0000000..68176da
--- /dev/null
@@ -0,0 +1,208 @@
+package org.argeo.security.ui.rap;
+
+import org.argeo.security.ui.rap.commands.UserMenu;
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.commands.ICommandService;
+
+/** Eclipse rap specific action bar advisor */
+public class RapActionBarAdvisor extends ActionBarAdvisor {
+       private final static String ID_BASE = "org.argeo.security.ui.rap";
+       // private final static Log log = LogFactory
+       // .getLog(SecureActionBarAdvisor.class);
+
+       /** Null means anonymous */
+       private String username = null;
+
+//     private IAction logoutAction;
+//     private IWorkbenchAction openPerspectiveDialogAction;
+//     private IWorkbenchAction showViewMenuAction;
+//     private IWorkbenchAction preferences;
+//     private IWorkbenchAction saveAction;
+//     private IWorkbenchAction saveAllAction;
+//     private IWorkbenchAction closeAllAction;
+
+       public RapActionBarAdvisor(IActionBarConfigurer configurer, String username) {
+               super(configurer);
+               this.username = username;
+       }
+
+       protected void makeActions(IWorkbenchWindow window) {
+//             preferences = ActionFactory.PREFERENCES.create(window);
+//             register(preferences);
+//             openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
+//                             .create(window);
+//             register(openPerspectiveDialogAction);
+//             showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
+//             register(showViewMenuAction);
+//
+//             // logout
+//             logoutAction = ActionFactory.QUIT.create(window);
+//             // logoutAction = createLogoutAction();
+//             register(logoutAction);
+//
+//             // Save semantics
+//             saveAction = ActionFactory.SAVE.create(window);
+//             register(saveAction);
+//             saveAllAction = ActionFactory.SAVE_ALL.create(window);
+//             register(saveAllAction);
+//             closeAllAction = ActionFactory.CLOSE_ALL.create(window);
+//             register(closeAllAction);
+
+       }
+
+       protected void fillMenuBar(IMenuManager menuBar) {
+//             MenuManager fileMenu = new MenuManager("&File",
+//                             IWorkbenchActionConstants.M_FILE);
+//             MenuManager editMenu = new MenuManager("&Edit",
+//                             IWorkbenchActionConstants.M_EDIT);
+//             MenuManager windowMenu = new MenuManager("&Window",
+//                             IWorkbenchActionConstants.M_WINDOW);
+//
+//             menuBar.add(fileMenu);
+//             menuBar.add(editMenu);
+//             menuBar.add(windowMenu);
+//             // Add a group marker indicating where action set menus will appear.
+//             menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+//
+//             // File
+//             fileMenu.add(saveAction);
+//             fileMenu.add(saveAllAction);
+//             fileMenu.add(closeAllAction);
+//             fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+//             fileMenu.add(new Separator());
+//             fileMenu.add(logoutAction);
+//
+//             // Edit
+//             editMenu.add(preferences);
+//
+//             // Window
+//             windowMenu.add(openPerspectiveDialogAction);
+//             windowMenu.add(showViewMenuAction);
+       }
+
+       @Override
+       protected void fillCoolBar(ICoolBarManager coolBar) {
+               if (username != null) {
+                       ICommandService cmdService = (ICommandService) getActionBarConfigurer()
+                                       .getWindowConfigurer().getWorkbenchConfigurer()
+                                       .getWorkbench().getService(ICommandService.class);
+                       Category userMenus = cmdService.getCategory(ID_BASE + ".userMenus");
+                       if (!userMenus.isDefined())
+                               userMenus.define("User Menus", "User related menus");
+
+                       Command userMenu = cmdService.getCommand(ID_BASE
+                                       + ".userMenuCommand");
+                       if (userMenu.isDefined())
+                               userMenu.undefine();
+                       userMenu.define(username, "User menu actions", userMenus);
+                       userMenu.setHandler(new UserMenu());
+
+                       // userToolbar.add(new UserMenuAction());
+                       // coolBar.add(userToolbar);
+               } else {// anonymous
+                       IToolBarManager userToolbar = new ToolBarManager(SWT.FLAT
+                                       | SWT.RIGHT);
+                       //userToolbar.add(logoutAction);
+                       coolBar.add(userToolbar);
+               }
+               // IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT |
+               // SWT.RIGHT);
+               // saveToolbar.add(saveAction);
+               // saveToolbar.add(saveAllAction);
+               // coolBar.add(saveToolbar);
+       }
+
+       // class UserMenuAction extends Action implements IWorkbenchAction {
+       //
+       // public UserMenuAction() {
+       // super(username, IAction.AS_DROP_DOWN_MENU);
+       // // setMenuCreator(new UserMenu());
+       // }
+       //
+       // @Override
+       // public String getId() {
+       // return "org.argeo.security.ui.rap.userMenu";
+       // }
+       //
+       // @Override
+       // public void dispose() {
+       // }
+       //
+       // }
+
+       // class UserMenu implements IMenuCreator {
+       // private Menu menu;
+       //
+       // public Menu getMenu(Control parent) {
+       // Menu menu = new Menu(parent);
+       // addActionToMenu(menu, logoutAction);
+       // return menu;
+       // }
+       //
+       // private void addActionToMenu(Menu menu, IAction action) {
+       // ActionContributionItem item = new ActionContributionItem(action);
+       // item.fill(menu, -1);
+       // }
+       //
+       // public void dispose() {
+       // if (menu != null) {
+       // menu.dispose();
+       // }
+       // }
+       //
+       // public Menu getMenu(Menu parent) {
+       // // Not use
+       // return null;
+       // }
+       //
+       // }
+
+       // protected IAction createLogoutAction() {
+       // Subject subject = Subject.getSubject(AccessController.getContext());
+       // final String username = subject.getPrincipals().iterator().next()
+       // .getName();
+       //
+       // IAction logoutAction = new Action() {
+       // public String getId() {
+       // return SecureRapActivator.ID + ".logoutAction";
+       // }
+       //
+       // public String getText() {
+       // return "Logout " + username;
+       // }
+       //
+       // public void run() {
+       // // try {
+       // // Subject subject = SecureRapActivator.getLoginContext()
+       // // .getSubject();
+       // // String subjectStr = subject.toString();
+       // // subject.getPrincipals().clear();
+       // // SecureRapActivator.getLoginContext().logout();
+       // // log.info(subjectStr + " logged out");
+       // // } catch (LoginException e) {
+       // // log.error("Error when logging out", e);
+       // // }
+       // // SecureEntryPoint.logout(username);
+       // // PlatformUI.getWorkbench().close();
+       // // try {
+       // // RWT.getRequest().getSession().setMaxInactiveInterval(1);
+       // // } catch (Exception e) {
+       // // if (log.isTraceEnabled())
+       // // log.trace("Error when invalidating session", e);
+       // // }
+       // }
+       //
+       // };
+       // return logoutAction;
+       // }
+
+}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapSecureWorkbenchWindowAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapSecureWorkbenchWindowAdvisor.java
deleted file mode 100644 (file)
index 2875aa3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.security.ui.rap;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-
-public class RapSecureWorkbenchWindowAdvisor extends
-               SecureWorkbenchWindowAdvisor {
-       public RapSecureWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
-               super(configurer);
-       }
-
-       @Override
-       public ActionBarAdvisor createActionBarAdvisor(
-                       IActionBarConfigurer configurer) {
-               return new SecureActionBarAdvisor(configurer, false);
-       }
-
-       public void preWindowOpen() {
-               IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
-               configurer.setShowCoolBar(true);
-               configurer.setShowMenuBar(true);
-               configurer.setShowStatusLine(false);
-               configurer.setShowPerspectiveBar(true);
-               configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$
-               // Full screen, see
-               // http://dev.eclipse.org/newslists/news.eclipse.technology.rap/msg02697.html
-               configurer.setShellStyle(SWT.NONE);
-               Rectangle bounds = Display.getCurrent().getBounds();
-               configurer.setInitialSize(new Point(bounds.width, bounds.height));
-       }
-
-}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapWindowAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapWindowAdvisor.java
new file mode 100644 (file)
index 0000000..36ee278
--- /dev/null
@@ -0,0 +1,62 @@
+package org.argeo.security.ui.rap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/** Eclipse RAP specific window advisor */
+public class RapWindowAdvisor extends WorkbenchWindowAdvisor {
+
+       private String username;
+
+       public RapWindowAdvisor(IWorkbenchWindowConfigurer configurer,
+                       String username) {
+               super(configurer);
+               this.username = username;
+       }
+
+       @Override
+       public ActionBarAdvisor createActionBarAdvisor(
+                       IActionBarConfigurer configurer) {
+               return new RapActionBarAdvisor(configurer, username);
+       }
+
+       public void preWindowOpen() {
+               IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+               configurer.setShowCoolBar(true);
+               configurer.setShowMenuBar(false);
+               configurer.setShowStatusLine(false);
+               configurer.setShowPerspectiveBar(true);
+               configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$
+               // Full screen, see
+               // http://dev.eclipse.org/newslists/news.eclipse.technology.rap/msg02697.html
+               configurer.setShellStyle(SWT.NONE);
+               Rectangle bounds = Display.getCurrent().getBounds();
+               configurer.setInitialSize(new Point(bounds.width, bounds.height));
+       }
+
+       @Override
+       public void postWindowOpen() {
+               String defaultPerspective = getWindowConfigurer()
+                               .getWorkbenchConfigurer().getWorkbench()
+                               .getPerspectiveRegistry().getDefaultPerspective();
+               if (defaultPerspective == null) {
+                       IWorkbenchWindow window = getWindowConfigurer().getWindow();
+                       if (window == null)
+                               return;
+
+                       IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
+                                       .create(window);
+                       openPerspectiveDialogAction.run();
+               }
+       }
+
+}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapWorkbenchAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/RapWorkbenchAdvisor.java
new file mode 100644 (file)
index 0000000..b553dce
--- /dev/null
@@ -0,0 +1,38 @@
+package org.argeo.security.ui.rap;
+
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/** Eclipse RAP specific workbench advisor */
+public class RapWorkbenchAdvisor extends WorkbenchAdvisor {
+       public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
+       private String initialPerspective = System.getProperty(
+                       INITIAL_PERSPECTIVE_PROPERTY, null);
+
+       private String username;
+
+       public RapWorkbenchAdvisor(String username) {
+               this.username = username;
+       }
+
+       public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
+                       IWorkbenchWindowConfigurer configurer) {
+               return new RapWindowAdvisor(configurer, username);
+       }
+
+       public String getInitialWindowPerspectiveId() {
+               if (initialPerspective != null) {
+                       // check whether this user can see the declared perspective
+                       // (typically the perspective won't be listed if this user doesn't
+                       // have the right to see it)
+                       IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
+                                       .getPerspectiveRegistry()
+                                       .findPerspectiveWithId(initialPerspective);
+                       if (pd == null)
+                               return null;
+               }
+               return initialPerspective;
+       }
+}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java
deleted file mode 100644 (file)
index f47eb82..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-package org.argeo.security.ui.rap;
-
-import java.security.AccessController;
-
-import javax.security.auth.Subject;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.ICoolBarManager;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-
-public class SecureActionBarAdvisor extends ActionBarAdvisor {
-//     private final static Log log = LogFactory
-//                     .getLog(SecureActionBarAdvisor.class);
-
-       private IAction logoutAction;
-       private IWorkbenchAction openPerspectiveDialogAction;
-       private IWorkbenchAction showViewMenuAction;
-       private IWorkbenchAction preferences;
-       private IWorkbenchAction saveAction;
-       private IWorkbenchAction saveAllAction;
-       private IWorkbenchAction closeAllAction;
-
-       public SecureActionBarAdvisor(IActionBarConfigurer configurer, Boolean isRcp) {
-               super(configurer);
-       }
-
-       protected void makeActions(IWorkbenchWindow window) {
-               preferences = ActionFactory.PREFERENCES.create(window);
-               register(preferences);
-               openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
-                               .create(window);
-               register(openPerspectiveDialogAction);
-               showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
-               register(showViewMenuAction);
-
-               // logout
-               logoutAction = ActionFactory.QUIT.create(window);
-               //logoutAction = createLogoutAction();
-               register(logoutAction);
-
-               // Save semantics
-               saveAction = ActionFactory.SAVE.create(window);
-               register(saveAction);
-               saveAllAction = ActionFactory.SAVE_ALL.create(window);
-               register(saveAllAction);
-               closeAllAction = ActionFactory.CLOSE_ALL.create(window);
-               register(closeAllAction);
-
-       }
-
-       protected IAction createLogoutAction() {
-               Subject subject = Subject.getSubject(AccessController.getContext());
-               final String username = subject.getPrincipals().iterator().next()
-                               .getName();
-
-               IAction logoutAction = new Action() {
-                       public String getId() {
-                               return SecureRapActivator.ID + ".logoutAction";
-                       }
-
-                       public String getText() {
-                               return "Logout " + username;
-                       }
-
-                       public void run() {
-                               // try {
-                               // Subject subject = SecureRapActivator.getLoginContext()
-                               // .getSubject();
-                               // String subjectStr = subject.toString();
-                               // subject.getPrincipals().clear();
-                               // SecureRapActivator.getLoginContext().logout();
-                               // log.info(subjectStr + " logged out");
-                               // } catch (LoginException e) {
-                               // log.error("Error when logging out", e);
-                               // }
-//                             SecureEntryPoint.logout(username);
-//                             PlatformUI.getWorkbench().close();
-                               // try {
-                               // RWT.getRequest().getSession().setMaxInactiveInterval(1);
-                               // } catch (Exception e) {
-                               // if (log.isTraceEnabled())
-                               // log.trace("Error when invalidating session", e);
-                               // }
-                       }
-
-               };
-               return logoutAction;
-       }
-
-       protected void fillMenuBar(IMenuManager menuBar) {
-               MenuManager fileMenu = new MenuManager("&File",
-                               IWorkbenchActionConstants.M_FILE);
-               MenuManager editMenu = new MenuManager("&Edit",
-                               IWorkbenchActionConstants.M_EDIT);
-               MenuManager windowMenu = new MenuManager("&Window",
-                               IWorkbenchActionConstants.M_WINDOW);
-
-               menuBar.add(fileMenu);
-               menuBar.add(editMenu);
-               menuBar.add(windowMenu);
-               // Add a group marker indicating where action set menus will appear.
-               menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-
-               // File
-               fileMenu.add(saveAction);
-               fileMenu.add(saveAllAction);
-               fileMenu.add(closeAllAction);
-               fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-               fileMenu.add(new Separator());
-               fileMenu.add(logoutAction);
-
-               // Edit
-               editMenu.add(preferences);
-
-               // Window
-               windowMenu.add(openPerspectiveDialogAction);
-               windowMenu.add(showViewMenuAction);
-       }
-
-       @Override
-       protected void fillCoolBar(ICoolBarManager coolBar) {
-               IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
-               saveToolbar.add(saveAction);
-               saveToolbar.add(saveAllAction);
-               coolBar.add(saveToolbar);
-       }
-
-}
index 9f54e4c752c3918c536a2f6df92923c045344c60..e2febf0aeb9033ce74f09b33e8f1f1cf53cd8e6d 100644 (file)
@@ -8,20 +8,19 @@ import javax.security.auth.login.LoginException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
 import org.eclipse.equinox.security.auth.ILoginContext;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.rwt.RWT;
 import org.eclipse.rwt.lifecycle.IEntryPoint;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
 import org.springframework.security.BadCredentialsException;
 
 /**
- * RAP entry point with login capabilities. On the user has been authenticated,
- * the workbench is run as a privileged action by the related subject.
+ * RAP entry point with login capabilities. Once the user has been
+ * authenticated, the workbench is run as a privileged action by the related
+ * subject.
  */
 public class SecureEntryPoint implements IEntryPoint {
        private final static Log log = LogFactory.getLog(SecureEntryPoint.class);
@@ -31,7 +30,9 @@ public class SecureEntryPoint implements IEntryPoint {
         * not yet logged in.
         */
        private Integer loginTimeout = 1 * 60;
-       private Integer sessionTimeout = 15 * 60;
+       // TODO make it configurable
+       /** Default session timeout is 8 hours (European working day length) */
+       private Integer sessionTimeout = 8 * 60 * 60;
 
        @Override
        public int createUI() {
@@ -43,14 +44,12 @@ public class SecureEntryPoint implements IEntryPoint {
                        log.debug("THREAD=" + Thread.currentThread().getId()
                                        + ", sessionStore=" + RWT.getSessionStore().getId());
 
-               Integer returnCode = null;
-
                // create display
-               Display display = PlatformUI.createDisplay();
+               final Display display = PlatformUI.createDisplay();
 
                // log in
                final ILoginContext loginContext = SecureRapActivator
-                               .createLoginContext();
+                               .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
                Subject subject = null;
                tryLogin: while (subject == null && !display.isDisposed()) {
                        try {
@@ -64,37 +63,17 @@ public class SecureEntryPoint implements IEntryPoint {
                                        // retry login
                                        continue tryLogin;
                                }
-
-                               // check thread death
-                               ThreadDeath td = wasCausedByThreadDeath(e);
-                               if (td != null) {
-                                       display.dispose();
-                                       throw td;
-                               }
-
-                               if (!display.isDisposed()) {
-                                       org.argeo.eclipse.ui.Error.show(
-                                                       "Unexpected exception during authentication", e);
-                                       // this was not just bad credentials or death thread
-                                       RWT.getRequest().getSession().setMaxInactiveInterval(1);
-                                       display.dispose();
-                                       return -1;
-                               } else {
-                                       throw new ArgeoException(
-                                                       "Unexpected exception during authentication", e);
-                               }
+                               return processLoginDeath(display, e);
                        }
                }
 
-               // identify after successful login
+               // Once the user is logged in, she can have a longer session timeout
+               RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
                if (log.isDebugEnabled())
                        log.debug("Authenticated " + subject);
+
                final String username = subject.getPrincipals().iterator().next()
                                .getName();
-
-               // Once the user is logged in, she can have a longer session timeout
-               RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
-
                // Logout callback when the display is disposed
                display.disposeExec(new Runnable() {
                        public void run() {
@@ -106,13 +85,42 @@ public class SecureEntryPoint implements IEntryPoint {
                //
                // RUN THE WORKBENCH
                //
+               Integer returnCode = null;
                try {
-                       returnCode = (Integer) Subject.doAs(subject, getRunAction(display));
+                       returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
+                               public Integer run() {
+                                       RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor(
+                                                       username);
+                                       int result = PlatformUI.createAndRunWorkbench(display,
+                                                       workbenchAdvisor);
+                                       return new Integer(result);
+                               }
+                       });
                        logout(loginContext, username);
                } finally {
                        display.dispose();
                }
-               return processReturnCode(returnCode);
+               return returnCode;
+       }
+
+       private Integer processLoginDeath(Display display, LoginException e) {
+               // check thread death
+               ThreadDeath td = wasCausedByThreadDeath(e);
+               if (td != null) {
+                       display.dispose();
+                       throw td;
+               }
+               if (!display.isDisposed()) {
+                       ErrorFeedback.show("Unexpected exception during authentication", e);
+                       // this was not just bad credentials or death thread
+                       RWT.getRequest().getSession().setMaxInactiveInterval(1);
+                       display.dispose();
+                       return -1;
+               } else {
+                       throw new ArgeoException(
+                                       "Unexpected exception during authentication", e);
+               }
+
        }
 
        /** Recursively look for {@link BadCredentialsException} in the root causes. */
@@ -149,36 +157,4 @@ public class SecureEntryPoint implements IEntryPoint {
                        log.error("Erorr when logging out", e);
                }
        }
-
-       @SuppressWarnings("rawtypes")
-       private PrivilegedAction getRunAction(final Display display) {
-               return new PrivilegedAction() {
-                       public Object run() {
-                               int result = createAndRunWorkbench(display);
-                               return new Integer(result);
-                       }
-               };
-       }
-
-       /** To be overridden */
-       protected Integer createAndRunWorkbench(Display display) {
-               return PlatformUI.createAndRunWorkbench(display,
-                               createWorkbenchAdvisor());
-       }
-
-       /** To be overridden */
-       protected Integer processReturnCode(Integer returnCode) {
-               return returnCode;
-       }
-
-       /** To be overridden */
-       protected WorkbenchAdvisor createWorkbenchAdvisor() {
-               return new SecureWorkbenchAdvisor() {
-                       public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
-                                       IWorkbenchWindowConfigurer configurer) {
-                               return new RapSecureWorkbenchWindowAdvisor(configurer);
-                       }
-
-               };
-       }
 }
index 762b227830f1d5b120a461f6958560a1ff63371b..97c1c579801dd3c3ae5d2c3f805673ea95897e7b 100644 (file)
@@ -12,19 +12,33 @@ public class SecureRapActivator implements BundleActivator {
 
        public final static String ID = "org.argeo.security.ui.rap";
        public final static String CONTEXT_SPRING = "SPRING";
+       public final static String CONTEXT_SPRING_ANONYMOUS = "SPRING_ANONYMOUS";
        private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
 
-       private static BundleContext bundleContext;
+       private BundleContext bundleContext;
+       private static SecureRapActivator activator = null;
 
        public void start(BundleContext bundleContext) throws Exception {
-               SecureRapActivator.bundleContext = bundleContext;
+               activator = this;
+               this.bundleContext = bundleContext;
        }
 
        public void stop(BundleContext context) throws Exception {
+               bundleContext = null;
+               activator = null;
        }
 
-       static ILoginContext createLoginContext() {
-               URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE);
-               return LoginContextFactory.createContext(CONTEXT_SPRING, configUrl);
+       public BundleContext getBundleContext() {
+               return bundleContext;
+       }
+
+       public static SecureRapActivator getActivator() {
+               return activator;
+       }
+
+       static ILoginContext createLoginContext(String contextName) {
+               URL configUrl = getActivator().getBundleContext().getBundle()
+                               .getEntry(JAAS_CONFIG_FILE);
+               return LoginContextFactory.createContext(contextName, configUrl);
        }
 }
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureWorkbenchAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureWorkbenchAdvisor.java
deleted file mode 100644 (file)
index c2d7400..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.argeo.security.ui.rap;
-
-import org.eclipse.ui.IPerspectiveDescriptor;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-public class SecureWorkbenchAdvisor extends WorkbenchAdvisor {
-       public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
-       private String initialPerspective = System.getProperty(
-                       INITIAL_PERSPECTIVE_PROPERTY, null);
-
-       public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
-                       IWorkbenchWindowConfigurer configurer) {
-               return new SecureWorkbenchWindowAdvisor(configurer);
-       }
-
-       public String getInitialWindowPerspectiveId() {
-               if (initialPerspective != null) {
-                       // check whether this user can see the declared perspective
-                       // (typically the perspective won't be listed if this user doesn't
-                       // have the right to see it)
-                       IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
-                                       .getPerspectiveRegistry()
-                                       .findPerspectiveWithId(initialPerspective);
-                       if(pd==null)
-                               return null;
-               }
-               return initialPerspective;
-       }
-}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureWorkbenchWindowAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureWorkbenchWindowAdvisor.java
deleted file mode 100644 (file)
index c2675d5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.argeo.security.ui.rap;
-
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-public class SecureWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
-
-       public SecureWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
-               super(configurer);
-       }
-
-       public ActionBarAdvisor createActionBarAdvisor(
-                       IActionBarConfigurer configurer) {
-               return new SecureActionBarAdvisor(configurer, true);
-       }
-
-       public void preWindowOpen() {
-               IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
-               configurer.setInitialSize(new Point(1200, 900));
-               configurer.setShowCoolBar(true);
-               configurer.setShowMenuBar(true);
-               configurer.setShowStatusLine(false);
-
-               configurer.setShowPerspectiveBar(true);
-               configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$
-       }
-
-       @Override
-       public void postWindowOpen() {
-               String defaultPerspective = getWindowConfigurer()
-                               .getWorkbenchConfigurer().getWorkbench()
-                               .getPerspectiveRegistry().getDefaultPerspective();
-               if (defaultPerspective == null) {
-                       IWorkbenchWindow window = getWindowConfigurer().getWindow();
-                       if (window == null)
-                               return;
-
-                       IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
-                                       .create(window);
-                       openPerspectiveDialogAction.run();
-               }
-       }
-
-}
diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/commands/UserMenu.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/commands/UserMenu.java
new file mode 100644 (file)
index 0000000..7fdc016
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.security.ui.rap.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+
+/** Default action of the user menu */
+public class UserMenu extends AbstractHandler {
+
+       @Override
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               return null;
+       }
+
+}
diff --git a/security/plugins/org.argeo.security.ui/icons/home.gif b/security/plugins/org.argeo.security.ui/icons/home.gif
new file mode 100644 (file)
index 0000000..fd0c669
Binary files /dev/null and b/security/plugins/org.argeo.security.ui/icons/home.gif differ
diff --git a/security/plugins/org.argeo.security.ui/icons/user.gif b/security/plugins/org.argeo.security.ui/icons/user.gif
new file mode 100644 (file)
index 0000000..90a0014
Binary files /dev/null and b/security/plugins/org.argeo.security.ui/icons/user.gif differ
index 9146615326a44b0983ad105e7a76b4579fead1fa..6f688635991cdd194a6f253151cd2f5d2014f80f 100644 (file)
             class="org.argeo.security.ui.dialogs.DefaultLoginDialog">
       </callbackHandler>
    </extension>
-   <extension
-         point="org.eclipse.ui.commands">
-      <command
-            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
-            id="org.argeo.security.ui.openChangePasswordDialog"
-            name="OpenChangePasswordDialog">
-      </command>
-    </extension>
-     <extension
-         point="org.eclipse.ui.menus">
-        <menuContribution
-                locationURI="menu:file?after=additions">
-                <command
-                      commandId="org.argeo.security.ui.openChangePasswordDialog"
-                      icon="icons/password.gif"
-                      label="Change password"
-                      style="push"
-                      tooltip="Change password">
-                </command>
-          </menuContribution>
-  </extension>
-   <extension
-           point="org.eclipse.ui.services">
+   <extension point="org.eclipse.ui.services">
         <sourceProvider
               provider="org.argeo.security.ui.RolesSourceProvider">
            <variable
            </variable>
         </sourceProvider>
      </extension>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            class="org.argeo.security.ui.views.UserProfile"
+            icon="icons/user.gif"
+            id="org.argeo.security.ui.userProfile"
+            name="Profile"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            class="org.argeo.security.ui.UserHomePerspective"
+            icon="icons/home.gif"
+            id="org.argeo.security.ui.userHomePerspective"
+            name="Home">
+      </perspective>
+   </extension>
  </plugin>
diff --git a/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/UserHomePerspective.java b/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/UserHomePerspective.java
new file mode 100644 (file)
index 0000000..eb48d1d
--- /dev/null
@@ -0,0 +1,20 @@
+package org.argeo.security.ui;
+
+import org.argeo.security.ui.views.UserProfile;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class UserHomePerspective implements IPerspectiveFactory {
+       public void createInitialLayout(IPageLayout layout) {
+               String editorArea = layout.getEditorArea();
+               layout.setEditorAreaVisible(true);
+               layout.setFixed(false);
+
+               IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
+                               0.65f, editorArea);
+               left.addView(UserProfile.ID);
+//             left.addView(RolesView.ID);
+       }
+
+}
diff --git a/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/views/UserProfile.java b/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/views/UserProfile.java
new file mode 100644 (file)
index 0000000..afa5694
--- /dev/null
@@ -0,0 +1,22 @@
+package org.argeo.security.ui.views;
+
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.argeo.security.ui.internal.CurrentUser;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.part.ViewPart;
+
+public class UserProfile extends ViewPart {
+       public static String ID = SecurityUiPlugin.PLUGIN_ID + ".userProfile";
+
+       @Override
+       public void createPartControl(Composite parent) {
+               new Label(parent, SWT.NONE).setText(CurrentUser.getUsername());
+       }
+
+       @Override
+       public void setFocus() {
+       }
+
+}
index 5cc7f43a7bffd116c3e9e79915517209115a7cb1..3e9f015bb879258fe1c6fd3e94a71ca603e9c34d 100644 (file)
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.core.DefaultSecurityManager;
+import org.apache.jackrabbit.core.security.AnonymousPrincipal;
 import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
 import org.argeo.ArgeoException;
@@ -49,7 +50,10 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
 
                if (log.isTraceEnabled())
                        log.trace(subject);
-               // skip Jackrabbit system user
+               // skip anonymous user (no rights)
+               if (!subject.getPrincipals(AnonymousPrincipal.class).isEmpty())
+                       return super.getUserID(subject, workspaceName);
+               // skip Jackrabbit system user (all rights)
                if (!subject.getPrincipals(ArgeoSystemPrincipal.class).isEmpty())
                        return super.getUserID(subject, workspaceName);