1 /*
2 * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/login/CommandLineAccessHandler.java,v $
3 * $Revision: 1.13 $
4 *
5 * Copyright (C) 2006 Tim Pizey
6 *
7 * Part of Melati (http://melati.org), a framework for the rapid
8 * development of clean, maintainable web applications.
9 *
10 * Melati is free software; Permission is granted to copy, distribute
11 * and/or modify this software under the terms either:
12 *
13 * a) the GNU General Public License as published by the Free Software
14 * Foundation; either version 2 of the License, or (at your option)
15 * any later version,
16 *
17 * or
18 *
19 * b) any version of the Melati Software License, as published
20 * at http://melati.org
21 *
22 * You should have received a copy of the GNU General Public License and
23 * the Melati Software License along with this program;
24 * if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26 * GNU General Public License and visit http://melati.org to obtain the
27 * Melati Software License.
28 *
29 * Feel free to contact the Developers of Melati (http://melati.org),
30 * if you would like to work out a different arrangement than the options
31 * outlined here. It is our intention to allow Melati to be used by as
32 * wide an audience as possible.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * Contact details for copyright holder:
40 *
41 * Tim Pizey <timp At paneris.org>
42 * http://paneris.org/~timp
43 */
44 package org.melati.login;
45
46 import java.io.BufferedReader;
47 import java.io.IOException;
48 import java.io.InputStream;
49 import java.io.InputStreamReader;
50 import java.io.PrintStream;
51
52 import org.melati.Melati;
53 import org.melati.poem.AccessPoemException;
54 import org.melati.poem.PoemThread;
55 import org.melati.poem.User;
56 import org.melati.poem.util.ArrayUtils;
57 import org.melati.util.MelatiException;
58
59 /**
60 * A handler invoked when an {@link AccessPoemException} is thrown.
61 *
62 * If the application is invoked without a username and password on the command
63 * line then the user will be prompted for them.
64 *
65 * If the usename is supplied then the user will not be prompted as this migth
66 * interfere with use in a scripting environment.
67 *
68 * @see org.melati.login.AccessHandler
69 */
70 public class CommandLineAccessHandler implements AccessHandler {
71
72 private PrintStream output = System.out;
73
74 private InputStream input = System.in;
75
76 private boolean commandLineUserCredentialsSet = false;
77
78 BufferedReader inputReader = null;
79
80 /**
81 * Constructor.
82 */
83 public CommandLineAccessHandler() {
84 super();
85 commandLineUserCredentialsSet = false;
86 }
87
88
89 /**
90 * Actually handle the {@link AccessPoemException}.
91 *
92 * {@inheritDoc}
93 *
94 * @see org.melati.login.AccessHandler#handleAccessException
95 * (org.melati.Melati, org.melati.poem.AccessPoemException)
96 */
97 public void handleAccessException(Melati melati,
98 AccessPoemException accessException) throws Exception {
99 Authorization auth = null;
100 boolean loggedIn = false;
101 if (!commandLineUserCredentialsSet) {
102 inputReader = new BufferedReader(new InputStreamReader(input));
103 System.err.println(accessException.getMessage());
104 int goes = 0;
105 while (goes < 3 && loggedIn == false) {
106 goes++;
107 auth = Authorization.from(inputReader, output);
108 if (auth != null) {
109
110 User user = null;
111 // They have tried to log in
112 if (auth.username != null) {
113 user = (User) melati.getDatabase().getUserTable().getLoginColumn()
114 .firstWhereEq(auth.username);
115 }
116 if (user != null && user.getPassword_unsafe().equals(auth.password)) {
117 // Login/password authentication succeeded
118 // Add the arguments to the stored Melati
119 String[] args = melati.getArguments();
120 args = (String[]) ArrayUtils.added(args, "-u");
121 args = (String[]) ArrayUtils.added(args, auth.username);
122 args = (String[]) ArrayUtils.added(args, "-p");
123 args = (String[]) ArrayUtils.added(args, auth.password);
124 melati.setArguments(args);
125 loggedIn = true;
126 } else {
127 System.err.println("Unknown username"); // ;)
128 }
129 }
130 }
131 }
132 if (!loggedIn)
133 throw accessException;
134 }
135
136 /**
137 * Called when the PoemTask is initialised, recalled after a login.
138 * {@inheritDoc}
139 *
140 * @see org.melati.login.AccessHandler#establishUser(org.melati.Melati)
141 */
142 public Melati establishUser(Melati melati) {
143 Authorization auth = Authorization.from(melati.getArguments());
144 if (auth == null) {
145 // No attempt to log in: become `guest'
146 PoemThread.setAccessToken(melati.getDatabase().guestAccessToken());
147 return melati;
148 } else {
149 commandLineUserCredentialsSet = true;
150 // They have tried to login or set command line parameters
151 User user = null;
152 user = (User) melati.getDatabase().getUserTable().getLoginColumn()
153 .firstWhereEq(auth.username);
154 if (user == null || !user.getPassword_unsafe().equals(auth.password)) {
155 // We just let the user try again as
156 // `guest' and hopefully trigger the same problem and get the same
157 // message all over again.
158 PoemThread.setAccessToken(melati.getDatabase().guestAccessToken());
159 return melati;
160 } else {
161 // Login/password authentication succeeded
162 PoemThread.setAccessToken(user);
163 return melati;
164 }
165 }
166 }
167
168 /**
169 * A no-op in a command line application.
170 *
171 * {@inheritDoc}
172 *
173 * @see org.melati.login.AccessHandler#buildRequest(org.melati.Melati)
174 */
175 public void buildRequest(Melati melati) throws MelatiException, IOException {
176 // Nothing to do here
177 }
178
179 /**
180 * @param input
181 * The input to set.
182 */
183 public void setInput(InputStream input) {
184 this.input = input;
185 }
186
187 /**
188 * @param output
189 * The output to set.
190 */
191 public void setOutput(PrintStream output) {
192 this.output = output;
193 }
194
195 }