HotelGuiSsoAuthenticator.java
1 |
/*
|
---|---|
2 |
** Module : HotelGuiSsoAuthenticator.java
|
3 |
** Abstract : SsoAuthenticator implementation for hotel_gui.
|
4 |
**
|
5 |
** Copyright (c) 2023, Golden Code Development Corporation.
|
6 |
**
|
7 |
** _#_ _I_ __Date__ ________________________________Description___________________________________
|
8 |
** 001 GBB 20231005 Created initial version.
|
9 |
*/
|
10 |
/*
|
11 |
** This program is free software: you can redistribute it and/or modify
|
12 |
** it under the terms of the GNU Affero General Public License as
|
13 |
** published by the Free Software Foundation, either version 3 of the
|
14 |
** License, or (at your option) any later version.
|
15 |
**
|
16 |
** This program is distributed in the hope that it will be useful,
|
17 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
** GNU Affero General Public License for more details.
|
20 |
**
|
21 |
** You may find a copy of the GNU Affero GPL version 3 at the following
|
22 |
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
|
23 |
**
|
24 |
** Additional terms under GNU Affero GPL version 3 section 7:
|
25 |
**
|
26 |
** Under Section 7 of the GNU Affero GPL version 3, the following additional
|
27 |
** terms apply to the works covered under the License. These additional terms
|
28 |
** are non-permissive additional terms allowed under Section 7 of the GNU
|
29 |
** Affero GPL version 3 and may not be removed by you.
|
30 |
**
|
31 |
** 0. Attribution Requirement.
|
32 |
**
|
33 |
** You must preserve all legal notices or author attributions in the covered
|
34 |
** work or Appropriate Legal Notices displayed by works containing the covered
|
35 |
** work. You may not remove from the covered work any author or developer
|
36 |
** credit already included within the covered work.
|
37 |
**
|
38 |
** 1. No License To Use Trademarks.
|
39 |
**
|
40 |
** This license does not grant any license or rights to use the trademarks
|
41 |
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
|
42 |
** of Golden Code Development Corporation. You are not authorized to use the
|
43 |
** name Golden Code, FWD, or the names of any author or contributor, for
|
44 |
** publicity purposes without written authorization.
|
45 |
**
|
46 |
** 2. No Misrepresentation of Affiliation.
|
47 |
**
|
48 |
** You may not represent yourself as Golden Code Development Corporation or FWD.
|
49 |
**
|
50 |
** You may not represent yourself for publicity purposes as associated with
|
51 |
** Golden Code Development Corporation, FWD, or any author or contributor to
|
52 |
** the covered work, without written authorization.
|
53 |
**
|
54 |
** 3. No Misrepresentation of Source or Origin.
|
55 |
**
|
56 |
** You may not represent the covered work as solely your work. All modified
|
57 |
** versions of the covered work must be marked in a reasonable way to make it
|
58 |
** clear that the modified work is not originating from Golden Code Development
|
59 |
** Corporation or FWD. All modified versions must contain the notices of
|
60 |
** attribution required in this license.
|
61 |
*/
|
62 |
package com.goldencode.hotel; |
63 |
|
64 |
import com.goldencode.p2j.directory.*; |
65 |
import com.goldencode.p2j.main.*; |
66 |
import com.goldencode.p2j.persist.*; |
67 |
import com.goldencode.p2j.security.*; |
68 |
import com.goldencode.p2j.util.*; |
69 |
import com.goldencode.p2j.util.logging.*; |
70 |
import com.goldencode.util.*; |
71 |
|
72 |
import javax.servlet.http.*; |
73 |
import java.lang.*; |
74 |
import java.sql.*; |
75 |
import java.util.*; |
76 |
import java.util.logging.*; |
77 |
|
78 |
/** SsoAuthenticator implementation for hotel_gui */
|
79 |
public class HotelGuiSsoAuthenticator |
80 |
implements SsoAuthenticator
|
81 |
{ |
82 |
/** Logger. */
|
83 |
private static final CentralLogger LOG = CentralLogger.get(HotelGuiSsoAuthenticator.class); |
84 |
|
85 |
/** Select query for prepared statement to check for user / pass */
|
86 |
private static final String QUERY_SELECT_COUNT_MATCHING_CREDS = |
87 |
"SELECT COUNT(*) as count FROM meta_user WHERE userid = upper(rtrim(?)) AND password = ?";
|
88 |
|
89 |
/** Database connection. */
|
90 |
private static Connection dbConnection; |
91 |
|
92 |
/** Database connection. */
|
93 |
private String defaultFwdAccount; |
94 |
|
95 |
/**
|
96 |
* Provides options configured in directory under config/auth-mode/ssopluginoption. Plain text that can
|
97 |
* contain any number of configs to be parsed by the custom implementation of the authenticator. The
|
98 |
* method is called right after the current object is instantiated, before any authentication takes place.
|
99 |
*
|
100 |
* @param option
|
101 |
* Plain text that can contain any number of configs.
|
102 |
*/
|
103 |
@Override
|
104 |
public void setOption(String option) |
105 |
{ |
106 |
if (StringHelper.hasContent(option))
|
107 |
{ |
108 |
defaultFwdAccount = option; |
109 |
} |
110 |
} |
111 |
|
112 |
/**
|
113 |
* Receives as an argument the html template loaded from the standard location in the custom package or
|
114 |
* null if no resource present.
|
115 |
*
|
116 |
* @param loadedTemplate
|
117 |
* The html template loaded from the standard location in the custom root package or null.
|
118 |
*
|
119 |
* @return The inflated template ready to be served as login page or null.
|
120 |
*/
|
121 |
@Override
|
122 |
public String getLoginPage(String loadedTemplate) |
123 |
{ |
124 |
return null; |
125 |
} |
126 |
|
127 |
/**
|
128 |
* Validates the POST request data against an authentication provider (DB, 3rd party directory, custom
|
129 |
* auth server, etc) and returns a container with all details needed by the FWD framework to respond to
|
130 |
* the auth request and eventually spawn a new client with the specified authorization. If the FWD SDK
|
131 |
* script is used on the login page, the parameters map contains {@link #FWD_SDK_LOGIN_PARAM_USER} and
|
132 |
* {@link #FWD_SDK_LOGIN_PARAM_PASS}.
|
133 |
*
|
134 |
* @param paramMap
|
135 |
* A map of all query / form params.
|
136 |
* @param cookies
|
137 |
* All cookies coming with the HTTP request.
|
138 |
* @param licensingData
|
139 |
* Data that can be used for enforcing licensing policy.
|
140 |
*
|
141 |
* @return A container with all details needed by the FWD framework to spawn a new client.
|
142 |
*/
|
143 |
@Override
|
144 |
public Result authenticate(Map<String, String[]> paramMap, Cookie[] cookies, LicensingData licensingData) |
145 |
{ |
146 |
if (dbConnection == null) |
147 |
{ |
148 |
try
|
149 |
{ |
150 |
connectToDb(); |
151 |
} |
152 |
catch (Throwable e) |
153 |
{ |
154 |
LOG.severe("Can't connect to db.", e);
|
155 |
return generateFailedAuthResult();
|
156 |
} |
157 |
} |
158 |
|
159 |
String appUser = paramMap.get(FWD_SDK_LOGIN_PARAM_USER)[0]; |
160 |
String appPass = paramMap.get(FWD_SDK_LOGIN_PARAM_PASS)[0]; |
161 |
String encodedPass = SecurityOps.encode(appPass).toStringMessage();
|
162 |
|
163 |
try
|
164 |
{ |
165 |
PreparedStatement stmt = dbConnection.prepareStatement(QUERY_SELECT_COUNT_MATCHING_CREDS);
|
166 |
stmt.setString(1, appUser);
|
167 |
stmt.setString(2, encodedPass);
|
168 |
ResultSet resultSet = stmt.executeQuery();
|
169 |
if (!resultSet.next() || resultSet.getInt("count") == 0) |
170 |
{ |
171 |
LOG.log(Level.FINER, "Cant authenticate the user %s against the db.", appUser); |
172 |
return generateFailedAuthResult();
|
173 |
} |
174 |
} |
175 |
catch (SQLException e) |
176 |
{ |
177 |
LOG.log(Level.FINER, e, "Cant authenticate the user %s against the db.", appUser); |
178 |
return generateFailedAuthResult();
|
179 |
} |
180 |
|
181 |
return new Result(true, defaultFwdAccount, appUser, null, null); |
182 |
} |
183 |
|
184 |
/**
|
185 |
* Invalidates the web session associated with the authentication cookie by communicating with the auth
|
186 |
* server or updating the DB and returns a cookie with the same name, but invalid value.
|
187 |
*
|
188 |
* @param cookies
|
189 |
* The cookie to be returned to the browser and used in the next auth requests.
|
190 |
*
|
191 |
* @return <code>null</code> if the web session / cookie invalidation failed, otherwise an
|
192 |
* authentication Cookie with invalid value.
|
193 |
*/
|
194 |
@Override
|
195 |
public Cookie logout(Cookie[] cookies) |
196 |
{ |
197 |
return null; |
198 |
} |
199 |
|
200 |
/**
|
201 |
* Synchronized class method to load the DB configurations, driver and establish the connection.
|
202 |
*
|
203 |
* @throws ClassNotFoundException
|
204 |
* May get produced by loading the driver class, if it's not in the classpath.
|
205 |
* @throws SQLException
|
206 |
* May get produced by trying to establish the DB connection.
|
207 |
*/
|
208 |
private static synchronized void connectToDb() |
209 |
throws ClassNotFoundException, |
210 |
SQLException
|
211 |
{ |
212 |
if (dbConnection != null) |
213 |
{ |
214 |
return;
|
215 |
} |
216 |
|
217 |
String dbName = DatabaseManager.loadedOnStartup().get(0); |
218 |
|
219 |
DirectoryService ds = DirectoryService.getInstance(); |
220 |
ds.bind(); |
221 |
String driverClass = getDirString(ds, "database/" + dbName + "/orm/connection/driver_class"); |
222 |
String url = getDirString(ds, "database/" + dbName + "/orm/connection/url"); |
223 |
String username = getDirString(ds, "database/" + dbName + "/orm/connection/username"); |
224 |
String password = getDirString(ds, "database/" + dbName + "/orm/connection/password"); |
225 |
ds.unbind(); |
226 |
|
227 |
// load db driver
|
228 |
Class.forName(driverClass);
|
229 |
|
230 |
dbConnection = DriverManager.getConnection(url, username, password);
|
231 |
} |
232 |
|
233 |
/**
|
234 |
* Convenience method to get the string from directory node.
|
235 |
*
|
236 |
* @param ds
|
237 |
* Bound directory service.
|
238 |
* @param nodeId
|
239 |
* The node path.
|
240 |
*
|
241 |
* @return Returns the string value found in the specified note or null.
|
242 |
*/
|
243 |
private static String getDirString(DirectoryService ds, String nodeId) |
244 |
{ |
245 |
return Utils.getDirectoryNodeString(ds, nodeId, null,false); |
246 |
} |
247 |
|
248 |
/**
|
249 |
* Returns the result, when the authentication fails.
|
250 |
*
|
251 |
* @return See above.
|
252 |
*/
|
253 |
private static Result generateFailedAuthResult() |
254 |
{ |
255 |
return new Result(false, WebDriverHandler.SupportedHttpCode.UNAUTHORIZED, null); |
256 |
} |
257 |
} |