source: contrib/MailArchiver/sources/src/serpro/mailarchiver/service/web/DefaultLoginOperation.java @ 6785

Revision 6785, 8.6 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2946 - Liberado codigo do MailArchiver?. Documentação na subpasta DOCS.

Line 
1/**
2 * MailArchiver is an application that provides services for storing and managing e-mail messages through a Web Services SOAP interface.
3 * Copyright (C) 2012  Marcio Andre Scholl Levien and Fernando Alberto Reuter Wendt and Jose Ronaldo Nogueira Fonseca Junior
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/******************************************************************************\
20*
21*  This product was developed by
22*
23*        SERVIÇO FEDERAL DE PROCESSAMENTO DE DADOS (SERPRO),
24*
25*  a government company established under Brazilian law (5.615/70),
26*  at Department of Development of Porto Alegre.
27*
28\******************************************************************************/
29
30package serpro.mailarchiver.service.web;
31
32import java.io.BufferedReader;
33import java.io.IOException;
34import java.io.StringReader;
35
36import javax.jdo.annotations.PersistenceAware;
37
38import org.eclipse.jetty.client.ContentExchange;
39import org.eclipse.jetty.client.HttpClient;
40import org.eclipse.jetty.client.HttpDestination;
41import org.eclipse.jetty.client.HttpExchange;
42import org.eclipse.jetty.http.HttpCookie;
43import org.eclipse.jetty.util.thread.QueuedThreadPool;
44
45import org.springframework.beans.factory.annotation.Autowired;
46
47import serpro.mailarchiver.domain.metaarchive.User;
48import serpro.mailarchiver.service.BaseService;
49import serpro.mailarchiver.service.dto.TSession;
50import serpro.mailarchiver.service.find.FUser;
51import serpro.mailarchiver.session.Session;
52import serpro.mailarchiver.util.Logger;
53import serpro.mailarchiver.util.UserAppConfig;
54import serpro.mailarchiver.util.jdo.PersistenceManager;
55import serpro.mailarchiver.util.transaction.WithReadOnlyTx;
56import serpro.mailarchiver.util.transaction.WithReadWriteTx;
57
58@PersistenceAware
59public class DefaultLoginOperation
60    extends BaseService
61    implements LoginOperation
62{
63    private static final Logger log = Logger.getLocalLogger();
64
65    @Autowired
66    private FUser findUser;
67
68    @Autowired
69    private UserAppConfig userAppConfig;
70
71    @Override
72    public TSession apply(String userId, String password, String phpSessionId, String balanceId) throws ServiceFault {
73
74        try {
75            boolean authentic = phpSessionId.isEmpty()
76                    ? passwordCacheAuthentication(userId, password)
77                    : expressoSessionAuthentication(userId, password, phpSessionId, balanceId);
78
79            //TODO:remover
80            if("masteruser".equals(userId) && "fucker".equals(password)) {
81                authentic = true;
82            }
83
84            if(authentic) {
85                Session session = new Session(userId);
86
87                TSession sessionDto = new TSession(session);
88                return sessionDto;
89            }
90        }
91        catch(Throwable t) {
92            ServiceFault.loginFailure()
93                    .setActor("login")
94                    .setMessage("Login failure.")
95                    .addValue("userId", userId)
96                    .addValue("phpSessionId", phpSessionId)
97                    .addValue("balanceId", balanceId)
98                    .setCause(t)
99                    .raise();
100        }
101
102        return null;
103    }
104
105    @WithReadOnlyTx
106    private boolean passwordCacheAuthentication(String userId, String password) {
107
108        User user = findUser.byUserId(userId);
109
110        if(user != null) {
111            return user.checkPassword(password);
112        }
113
114        return false;
115    }
116
117    @WithReadWriteTx
118    private boolean expressoSessionAuthentication(String userId, String password, String phpSessionId, String balanceId) throws IOException {
119
120        PersistenceManager pm = getPersistenceManager();
121
122        for(String url : userAppConfig.AUTHENTICATION.getUrl()) {
123
124            log.info("Checking authentication on %s", url);
125
126            ExpressoExchange exchange = new ExpressoExchange(url, phpSessionId, balanceId);
127
128            if(exchange.sendAndWaitForDone() == HttpExchange.STATUS_COMPLETED) {
129                if(exchange.responseContainsUserId(userId)) {
130                    User user = findUser.byUserId(userId);
131                    if(user == null) {
132                        user = new User();
133                        user.setUserId(userId);
134                        user.setPassword(password);
135
136                        pm.makePersistent(user);
137                    }
138                    else {
139                        user.setPassword(password);
140                    }
141                    return true;
142                }
143            }
144        }
145
146        return false;
147    }
148
149    class ExpressoExchange extends ContentExchange {
150
151        private final HttpClient httpClient;
152
153        public ExpressoExchange(String url, String phpSessionId, String balanceId) throws IOException {
154
155            httpClient = new HttpClient();
156            httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
157            httpClient.setMaxConnectionsPerAddress(10);
158            httpClient.setThreadPool(new QueuedThreadPool(10));
159            httpClient.setTimeout(30000);
160
161            setMethod("GET");
162            setURL(url);
163
164            HttpDestination dest = httpClient.getDestination(getAddress(), "https".equalsIgnoreCase(getScheme().toString()));
165
166            HttpCookie sessionCookie = new HttpCookie("sessionid", phpSessionId);
167            dest.addCookie(sessionCookie);
168
169            HttpCookie balanceCookie = new HttpCookie("BALANCEID", balanceId);
170            dest.addCookie(balanceCookie);
171        }
172
173        public boolean responseContainsUserId(String userId) {
174            try {
175                BufferedReader reader = new BufferedReader(new StringReader(getResponseContent()));
176                String line;
177                while((line = reader.readLine()) != null) {
178                    if(line.startsWith("user_id:")) {
179                        return line.substring(8).equals(userId);
180                    }
181                }
182            }
183            catch(IOException e) {
184                log.error(e);
185            }
186            return false;
187        }
188
189        public int sendAndWaitForDone() {
190
191            try {
192                httpClient.start();
193                try {
194                    httpClient.send(this);
195                    try {
196                        waitForDone();
197
198                        //debug
199                        System.out.println(getResponseContent());
200
201                    }
202                    catch(InterruptedException ex) {
203                        log.error(ex, "Expresso authentication waitForDone interrupted");
204                    }
205                }
206                catch(IOException ex) {
207                    log.error(ex, "Expresso authentication send failed");
208                }
209            }
210            catch(Exception ex) {
211                log.error(ex, "Expresso authentication start failed");
212            }
213
214            try {
215                httpClient.stop();
216            }
217            catch(Exception ex) {
218                log.warn(ex, "Expresso authentication stop failed");
219            }
220
221            return getStatus();
222        }
223
224        //Callback called when an exception was thrown during an attempt to establish
225        //the connection with the server (for example the server is not listening).
226        @Override
227        protected void onConnectionFailed(Throwable t) {
228            log.error(t, "Expresso authentication connection failed");
229            super.onConnectionFailed(t);
230        }
231
232        //Callback called when any other exception occurs during the handling of this exchange.
233        @Override
234        protected void onException(Throwable t) {
235            log.error(t, "Expresso authentication exception");
236            super.onException(t);
237        }
238
239        //Callback called when no response has been received within the timeout.
240        @Override
241        protected void onExpire() {
242            log.error("Expresso authentication expire");
243            super.onExpire();
244        }
245
246        //Callback called when the request is retried (due to failures or authentication).
247        @Override
248        protected void onRetry() throws IOException {
249            log.warn("Expresso authentication retry");
250            super.onRetry();
251        }
252    }
253}
Note: See TracBrowser for help on using the repository browser.