001 /* 002 Copyright (C) 2001-2002 Renaud Pawlak <renaud@aopsys.com>, 003 Laurent Martelli <laurent@aopsys.com> 004 005 This program is free software; you can redistribute it and/or modify 006 it under the terms of the GNU Lesser General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This program is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 GNU Lesser General Public License for more details. 014 015 You should have received a copy of the GNU Lesser General Public License 016 along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 018 019 package org.objectweb.jac.aspects.authentication; 020 021 import org.aopalliance.intercept.ConstructorInvocation; 022 import org.aopalliance.intercept.MethodInvocation; 023 import org.objectweb.jac.aspects.gui.*; 024 import org.objectweb.jac.core.*; 025 import org.objectweb.jac.core.AspectComponent; 026 import org.objectweb.jac.core.rtti.*; 027 import org.objectweb.jac.util.*; 028 029 /** 030 * This wrapper uses an authenticator and a controller to ensure that 031 * the current interaction is authenticated and allowed. 032 * 033 * @see AuthenticationAC 034 * @see Authenticator */ 035 036 public class AuthenticationWrapper extends Wrapper { 037 038 Authenticator authenticator; 039 MethodItem controller; 040 041 public Object invoke(MethodInvocation invocation) throws Throwable { 042 return authenticateAndControl((Interaction) invocation); 043 } 044 045 public Object construct(ConstructorInvocation invocation) 046 throws Throwable { 047 return authenticateAndControl((Interaction) invocation); 048 } 049 050 /** 051 * Constructs a new authentication wrapper. 052 * 053 * @param ac the aspect component that owns this wrapper 054 * @param authenticator the object that authenticates 055 * @param controller the method that grants the rights or not 056 */ 057 public AuthenticationWrapper( 058 AspectComponent ac, 059 Authenticator authenticator, 060 MethodItem controller) 061 { 062 super(ac); 063 Log.trace( 064 "authentication", 065 "new authentication wrapper: " + authenticator + "," + controller); 066 this.authenticator = authenticator; 067 this.controller = controller; 068 } 069 070 /** 071 * Sets the access rights controller. 072 * 073 * @param controller a static method of the prototype <code>boolean 074 * controller(String username,Object wrappee,MethodItem method)</code> 075 * @see org.objectweb.jac.aspects.user.UserAC#userController(String,Object,MethodItem) 076 * @see #dummyController(String,Object,MethodItem) 077 */ 078 public void setController(MethodItem controller) { 079 Log.trace( 080 "authentication", 081 "wrapper setController(" + controller + ")"); 082 this.controller = controller; 083 } 084 085 public void setAuthenticator(Authenticator authenticator) { 086 Log.trace( 087 "authentication", 088 "wrapper setAuthenticator(" + authenticator + ")"); 089 this.authenticator = authenticator; 090 } 091 092 /** 093 * This wrapping method authenticates a call on the wrapped method 094 * and controls that the authentcated user owns the rights to call 095 * it.<p> 096 * 097 * @return the value returned by the wrapped method 098 */ 099 public Object authenticateAndControl(Interaction interaction) 100 throws AuthenticationFailedException, AccessDeniedException, Throwable { 101 102 if (interaction.wrappee instanceof Display 103 && interaction.method.getName().equals("showCustomized")) { 104 CustomizedGUI cgui = (CustomizedGUI) interaction.args[1]; 105 if (cgui != null) { 106 Log.trace( 107 "application", 108 "auth sets application to " + cgui.getApplication()); 109 Collaboration.get().setCurApp(cgui.getApplication()); 110 } else { 111 Log.trace( 112 "application", 113 "auth cannot set the application since " 114 + "customized GUI is null"); 115 } 116 } 117 118 Log.trace( 119 "authentication", 120 "authenticate for method " 121 + interaction.method 122 + " on " 123 + interaction.wrappee); 124 Log.trace( 125 "authentication", 126 "name is: " + (String) attr(AuthenticationAC.USER)); 127 String name = (String) attr(AuthenticationAC.USER); 128 String password = null; 129 if (name == null) { 130 try { 131 name = authenticator.authenticate(); 132 Log.trace("authentication", "authenticated " + name); 133 attrdef(AuthenticationAC.USER, name); 134 } catch (Exception e) { 135 Log.trace( 136 "authentication", 137 "user authentication failed for " 138 + interaction.method 139 + " because of exception: " 140 + e); 141 e.printStackTrace(); 142 } 143 } 144 try { 145 Boolean allowed = 146 (Boolean) controller.invokeStatic( 147 new Object[] { 148 name, 149 interaction.wrappee, 150 interaction.method }); 151 if (allowed.booleanValue()) { 152 Log.trace( 153 "authentication", 154 "accesses granted to " 155 + name 156 + " for " 157 + interaction.method); 158 return proceed(interaction); 159 } else { 160 Log.trace( 161 "authentication", 162 "accesses denied to " 163 + name 164 + " for " 165 + interaction.method); 166 throw new AccessDeniedException( 167 accessDeniedMessage != null 168 ? accessDeniedMessage 169 : "you are not allowed to call " 170 + interaction.method 171 + " on " 172 + interaction.wrappee); 173 } 174 } catch (Exception e) { 175 Log.trace( 176 "authentication", 177 "accesses denied to " 178 + name 179 + " for " 180 + interaction.method 181 + " because of exception: " 182 + e); 183 Log.trace("authentication", 2, e); 184 throw new AccessDeniedException( 185 "you are not allowed to call " 186 + interaction.method 187 + " on " 188 + interaction.wrappee 189 + ": " 190 + e); 191 } 192 } 193 194 /** 195 * Returns true if the user is in the trusted users list. 196 * 197 * @param username the name of the user to check 198 * @return true if trusted 199 */ 200 public boolean isTrustedUser(String username) { 201 Log.trace( 202 "authentication", 203 "is trusted user: " + username + ":" + getAspectComponent()); 204 return ((AuthenticationAC) getAspectComponent()).isTrustedUser( 205 username); 206 } 207 208 String accessDeniedMessage = "Access denied"; 209 210 /** 211 * Sets the message to show when the access is denied. 212 * 213 * @param message the message 214 */ 215 public void setAccessDeniedMessage(String message) { 216 this.accessDeniedMessage = message; 217 } 218 219 /** 220 * This exception handler reacts when the access is denied. 221 * 222 * @param e the acces denied exception 223 */ 224 public void catchAccessDenied(AccessDeniedException e) { 225 Log.trace("authentication", "catching " + e.toString()); 226 DisplayContext context = 227 (DisplayContext) Collaboration.get().getAttribute( 228 GuiAC.DISPLAY_CONTEXT); 229 if (context != null) { 230 Display display = context.getDisplay(); 231 if (display != null) { 232 display.showMessage("Error", accessDeniedMessage); 233 return; 234 } 235 } 236 Log.error("no display available"); 237 } 238 239 /** 240 * Always return true. Use to force authentication. 241 * 242 * @param username the user's name 243 * @param wrappee the authenticated method 244 * @param method the authenticated method 245 */ 246 public static boolean dummyController( 247 String username, 248 Object wrappee, 249 MethodItem method) { 250 return true; 251 } 252 253 }