1 package de.fhdw.wtf.persistence.facade;
2
3 import java.security.MessageDigest;
4 import java.security.NoSuchAlgorithmException;
5 import java.sql.CallableStatement;
6 import java.sql.ResultSet;
7 import java.sql.SQLException;
8 import java.util.HashSet;
9 import java.util.Set;
10
11 import oracle.jdbc.OracleTypes;
12 import oracle.jdbc.internal.OracleCallableStatement;
13 import de.fhdw.wtf.persistence.exception.MandantNotLoggedInException;
14 import de.fhdw.wtf.persistence.exception.NameAlreadyExistsException;
15 import de.fhdw.wtf.persistence.exception.ObjectNotFoundException;
16 import de.fhdw.wtf.persistence.exception.OtherSQLException;
17 import de.fhdw.wtf.persistence.exception.PersistenceException;
18 import de.fhdw.wtf.persistence.exception.WrongPasswordException;
19 import de.fhdw.wtf.persistence.meta.Mandant;
20 import de.fhdw.wtf.persistence.meta.Role;
21 import de.fhdw.wtf.persistence.meta.User;
22 import de.fhdw.wtf.persistence.utils.IntegerConstants;
23
24
25
26
27
28 public class OracleAuthorizationFacadeImplementation implements AuthorizationFacade {
29
30 private boolean mandantLoggedIn;
31
32 private Mandant currentMandant;
33
34 private final String salt;
35
36 private final OracleDatabaseManager database;
37
38
39
40
41
42
43
44
45 public OracleAuthorizationFacadeImplementation(final String salt, final OracleDatabaseManager database) {
46 super();
47 this.salt = salt;
48 this.database = database;
49 this.currentMandant = null;
50 this.mandantLoggedIn = false;
51 }
52
53 @Override
54 public void logIn(final Mandant mandant) throws PersistenceException {
55 this.currentMandant = mandant;
56 if (!this.isPasswordCorrect(this.currentMandant.getId(), "root", this.currentMandant.getRootPassword())) {
57 throw new WrongPasswordException(mandant.getId(), "root");
58 }
59 try (final CallableStatement call =
60 this.database.getConnection().prepareCall("begin ? := accountfacade.getAllUsersForMandant(?); end;")) {
61 call.registerOutParameter(1, OracleTypes.CURSOR);
62 call.setString(2, this.currentMandant.getId());
63 call.execute();
64
65 try (final ResultSet result = ((OracleCallableStatement) call).getCursor(1)) {
66 while (result.next()) {
67 final String name = result.getString(3);
68 if (!name.equals("root")) {
69 final User entry = new User(result.getLong(1), name, result.getString(2));
70 this.currentMandant.addUser(entry);
71 }
72 }
73 }
74 this.mandantLoggedIn = true;
75 } catch (final SQLException e) {
76 throw new OtherSQLException(e);
77 }
78 }
79
80 @Override
81 public boolean isPasswordCorrect(final String mandant, final String username, final String password)
82 throws PersistenceException {
83 try {
84 final MessageDigest message = MessageDigest.getInstance("MD5");
85 message.update((password + this.salt).getBytes());
86 final String hashedPW = toHex(message.digest());
87
88 try (final CallableStatement call =
89 this.database.getConnection().prepareCall("begin ? := accountfacade.authorize(?,?,?); end;")) {
90 call.registerOutParameter(1, OracleTypes.NUMBER);
91 call.setString(2, mandant);
92 call.setString(IntegerConstants.THREE, username);
93 call.setString(IntegerConstants.FOUR, hashedPW);
94 call.execute();
95 return call.getInt(1) == 1;
96 } catch (final SQLException e) {
97 throw new OtherSQLException(e);
98 }
99 } catch (final NoSuchAlgorithmException e) {
100 e.printStackTrace();
101 return false;
102 }
103 }
104
105 private void checkMandantLogIn() throws PersistenceException {
106 if (!this.mandantLoggedIn) {
107 throw new MandantNotLoggedInException();
108 }
109 }
110
111 @Override
112 public User createUser(final String username, final String password) throws PersistenceException {
113 this.checkMandantLogIn();
114 final long id = this.createUser(this.currentMandant.getId(), username, password);
115 final User result = new User(id, username, this.currentMandant.getId());
116 this.currentMandant.addUser(result);
117 return result;
118 }
119
120 @Override
121 public void grantRoleToUser(final User user, final Role role) throws PersistenceException {
122 this.checkMandantLogIn();
123 try (final CallableStatement call =
124 this.database.getConnection().prepareCall("begin accountfacade.addRoleToUser(?,?); end;")) {
125 call.setLong(1, user.getId());
126 call.setLong(2, role.getId());
127 call.execute();
128 } catch (final SQLException e) {
129 throw new OtherSQLException(e);
130 }
131
132 }
133
134 @Override
135 public Role createRole(final String name) throws PersistenceException {
136 try (final CallableStatement call =
137 this.database.getConnection().prepareCall("begin ? := accountfacade.createRole(?); end;")) {
138 call.registerOutParameter(1, OracleTypes.NUMBER);
139 call.setString(2, name);
140 call.execute();
141 return new Role(call.getLong(1), name);
142 } catch (final SQLException e) {
143 if (e.getErrorCode() == NameAlreadyExistsException.ERRORCODE) {
144 throw new NameAlreadyExistsException(e);
145 }
146 e.printStackTrace();
147 throw new OtherSQLException(e);
148 }
149 }
150
151 @Override
152 public Set<Role> getRolesFrom(final User user) throws PersistenceException {
153 try (final CallableStatement call =
154 this.database.getConnection().prepareCall("begin ? := accountfacade.getRoles(?,?); end;")) {
155 call.registerOutParameter(1, OracleTypes.CURSOR);
156 call.setString(2, user.getMandantId());
157 call.setString(IntegerConstants.THREE, user.getName());
158 call.execute();
159 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
160 final Set<Role> result = new HashSet<>();
161 while (resultSet.next()) {
162 final Role entry = new Role(resultSet.getLong(1), resultSet.getString(2));
163 result.add(entry);
164 }
165 return result;
166 }
167 } catch (final SQLException e) {
168 throw new OtherSQLException(e);
169 }
170 }
171
172 private long createUser(final String mandant, final String username, final String password)
173 throws PersistenceException {
174 try {
175 final MessageDigest message = MessageDigest.getInstance("MD5");
176 message.update((password + this.salt).getBytes());
177 final String hashedPassword = toHex(message.digest());
178
179 try (final CallableStatement call =
180 this.database.getConnection().prepareCall("begin ? := accountfacade.createUser(?,?,?); end;")) {
181 call.registerOutParameter(1, OracleTypes.NUMBER);
182 call.setString(2, mandant);
183 call.setString(IntegerConstants.THREE, username);
184 call.setString(IntegerConstants.FOUR, hashedPassword);
185 call.execute();
186 return call.getLong(1);
187 } catch (final SQLException e) {
188 if (e.getErrorCode() == NameAlreadyExistsException.ERRORCODE) {
189 throw new NameAlreadyExistsException(e);
190 }
191 throw new OtherSQLException(e);
192 }
193 } catch (final NoSuchAlgorithmException e) {
194 e.printStackTrace();
195 throw new Error(e);
196 }
197 }
198
199 @Override
200 public Mandant createMandant(final String id, final String rootPassword) throws PersistenceException {
201 this.createUser(id, "root", rootPassword);
202 return new Mandant(id, rootPassword);
203 }
204
205 @Override
206 public Set<User> getUsers() throws PersistenceException {
207 this.checkMandantLogIn();
208 return this.currentMandant.getUsers();
209 }
210
211 @Override
212 public User getUser(final String mandant, final String name) throws PersistenceException {
213 try (final CallableStatement call =
214 this.database.getConnection().prepareCall("begin ? := accountfacade.getUser(?,?); end;")) {
215 call.registerOutParameter(1, OracleTypes.CURSOR);
216 call.setString(2, mandant);
217 call.setString(IntegerConstants.THREE, name);
218 call.execute();
219
220 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
221 if (resultSet.next()) {
222 return new User(resultSet.getLong(1), resultSet.getString(IntegerConstants.THREE),
223 resultSet.getString(2));
224 } else {
225
226 throw new ObjectNotFoundException();
227 }
228 }
229 } catch (final SQLException e) {
230 e.printStackTrace();
231 throw new OtherSQLException(e);
232 }
233 }
234
235 @Override
236 public Set<Role> listAllRoles() throws PersistenceException {
237 final Set<Role> result = new HashSet<>();
238 try (final CallableStatement call =
239 this.database.getConnection().prepareCall("begin ?:= accountfacade.getRoles; end;")) {
240 call.registerOutParameter(1, OracleTypes.CURSOR);
241 call.execute();
242
243 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
244 while (resultSet.next()) {
245 result.add(new Role(resultSet.getLong(1), resultSet.getString(2)));
246 }
247 }
248 } catch (final SQLException e) {
249 throw new OtherSQLException(e);
250 }
251
252 return result;
253 }
254
255 private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
256
257 private static String toHex(final byte[] bytes) {
258 final char[] hexChars = new char[bytes.length * 2];
259 for (int i = 0; i < bytes.length; i++) {
260 final int v = bytes[i] & 0xFF;
261 hexChars[i * 2] = hexArray[v >>> IntegerConstants.FOUR];
262 hexChars[i * 2 + 1] = hexArray[v & 0x0F];
263 }
264 return new String(hexChars);
265 }
266
267 }