001 /* 002 Copyright (C) 2002 Laurent Martelli <laurent@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.aspects.authentication; 019 020 import org.objectweb.jac.aspects.gui.DisplayContext; 021 import org.objectweb.jac.aspects.gui.GuiAC; 022 import org.objectweb.jac.core.Collaboration; 023 import org.objectweb.jac.core.Display; 024 import org.objectweb.jac.core.rtti.ClassRepository; 025 import org.objectweb.jac.core.rtti.MethodItem; 026 import org.objectweb.jac.util.Log; 027 028 /** 029 * This Authenticator ask for a username and password. The number of 030 * allowed attempts to enter a valid (username,password) is 031 * configurable. It needs a DisplayContext attribute in order to 032 * be able to interact with the user. */ 033 034 public abstract class PasswordAuthenticator implements Authenticator { 035 036 int retries = 3; 037 038 /** 039 * The default constructor with 3 retries in case of failing. */ 040 041 public PasswordAuthenticator() {} 042 043 /** 044 * This constructor can be used to parametrize the number of 045 * retries. 046 * 047 * @param retries the number of retries */ 048 049 public PasswordAuthenticator(int retries) { 050 this.retries = retries; 051 } 052 053 /** 054 * This method perform the authentication by calling the 055 * askUserNameAndPassword and checkPassword methods. 056 * 057 * @return the username if the authentication succeded, null 058 * otherwise 059 * 060 * @see #askUsernameAndPassword(String,String) 061 * @see #checkPassword(String,String) */ 062 063 public String authenticate() throws AuthenticationFailedException { 064 DisplayContext context = 065 (DisplayContext)Collaboration.get().getAttribute(GuiAC.DISPLAY_CONTEXT); 066 if (context!=null) { 067 Display display = context.getDisplay(); 068 MethodItem method = 069 ClassRepository.get().getClass(this).getMethod( 070 "askUsernameAndPassword"); 071 String username = null; 072 for (int i=retries; i>0 && username==null; i--) { 073 Object[] parameters = new Object[method.getParameterTypes().length]; 074 if (!display.showInput(this,method,parameters)) { 075 // cancel 076 Log.trace("authentication","Authentication cancelled"); 077 return null; 078 } 079 if (checkPassword((String)parameters[0],(String)parameters[1])) { 080 username = (String)parameters[0]; 081 } 082 } 083 if (username==null) { 084 throw new AuthenticationFailedException( 085 "Wrong username and password"); 086 } else { 087 return username; 088 } 089 } else { 090 Log.warning("no display context available, cannot authenticate user"); 091 return null; 092 } 093 } 094 095 /** 096 * This method has to be implemented by subclasses to perform the 097 * actual password checking mechanism. 098 * 099 * @param username the username 100 * @param password the password 101 * @return true if the username exists and if the password is valid 102 * for this username */ 103 104 abstract boolean checkPassword(String username, String password); 105 106 /** 107 * This empty method is used to popup a dialog on the current 108 * display so that the user can fill in the authentication 109 * information. 110 * 111 * @param username the username 112 * @param password the password */ 113 114 public void askUsernameAndPassword(String username, String password) {} 115 116 }