Bug 5060 Cannot Delete Users
[aaa.git] / aaa-h2-store / src / main / java / org / opendaylight / aaa / h2 / persistence / UserStore.java
1 /*
2  * Copyright (c) 2014, 2015 Hewlett-Packard Development Company, L.P. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.aaa.h2.persistence;
10
11 import com.google.common.base.Preconditions;
12
13 import java.sql.Connection;
14 import java.sql.DatabaseMetaData;
15 import java.sql.PreparedStatement;
16 import java.sql.ResultSet;
17 import java.sql.SQLException;
18 import java.sql.Statement;
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.opendaylight.aaa.api.IDMStoreUtil;
23 import org.opendaylight.aaa.api.SHA256Calculator;
24 import org.opendaylight.aaa.api.model.User;
25 import org.opendaylight.aaa.api.model.Users;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  *
31  * @author peter.mellquist@hp.com
32  *
33  */
34 public class UserStore {
35     private static final Logger LOG = LoggerFactory.getLogger(UserStore.class);
36     protected Connection dbConnection = null;
37     protected final static String SQL_ID = "userid";
38     protected final static String SQL_DOMAIN_ID = "domainid";
39     protected final static String SQL_NAME = "name";
40     protected final static String SQL_EMAIL = "email";
41     protected final static String SQL_PASSWORD = "password";
42     protected final static String SQL_DESCR = "description";
43     protected final static String SQL_ENABLED = "enabled";
44     protected final static String SQL_SALT = "salt";
45     public final static int MAX_FIELD_LEN = 128;
46
47     protected UserStore() {
48     }
49
50     protected Connection getDBConnect() throws StoreException {
51         dbConnection = H2Store.getConnection(dbConnection);
52         return dbConnection;
53     }
54
55     protected void dbClean() throws StoreException, SQLException {
56         Connection c = dbConnect();
57         String sql = "delete from users where true";
58         c.createStatement().execute(sql);
59         c.close();
60     }
61
62     protected Connection dbConnect() throws StoreException {
63         Connection conn;
64         try {
65             conn = getDBConnect();
66         } catch (StoreException se) {
67             throw se;
68         }
69         try {
70             DatabaseMetaData dbm = conn.getMetaData();
71             String[] tableTypes = { "TABLE" };
72             ResultSet rs = dbm.getTables(null, null, "USERS", tableTypes);
73             if (rs.next()) {
74                 LOG.debug("users Table already exists");
75             } else {
76                 LOG.info("users Table does not exist, creating table");
77                 Statement stmt = null;
78                 stmt = conn.createStatement();
79                 String sql = "CREATE TABLE users " + "(userid    VARCHAR(128) PRIMARY KEY,"
80                         + "name       VARCHAR(128)      NOT NULL, "
81                         + "domainid   VARCHAR(128)      NOT NULL, "
82                         + "email      VARCHAR(128)      NOT NULL, "
83                         + "password   VARCHAR(128)      NOT NULL, "
84                         + "description VARCHAR(128)     NOT NULL, "
85                         + "salt        VARCHAR(15)      NOT NULL, "
86                         + "enabled     INTEGER          NOT NULL)";
87                 stmt.executeUpdate(sql);
88                 stmt.close();
89             }
90         } catch (SQLException sqe) {
91             throw new StoreException("Cannot connect to database server " + sqe);
92         }
93         return conn;
94     }
95
96     protected void dbClose() {
97         if (dbConnection != null) {
98             try {
99                 dbConnection.close();
100             } catch (Exception e) {
101                 LOG.error("Cannot close Database Connection", e);
102             }
103         }
104     }
105
106     @Override
107     protected void finalize() throws Throwable {
108         dbClose();
109         super.finalize();
110     }
111
112     protected User rsToUser(ResultSet rs) throws SQLException {
113         User user = new User();
114         try {
115             user.setUserid(rs.getString(SQL_ID));
116             user.setDomainid(rs.getString(SQL_DOMAIN_ID));
117             user.setName(rs.getString(SQL_NAME));
118             user.setEmail(rs.getString(SQL_EMAIL));
119             user.setPassword(rs.getString(SQL_PASSWORD));
120             user.setDescription(rs.getString(SQL_DESCR));
121             user.setEnabled(rs.getInt(SQL_ENABLED) == 1 ? true : false);
122             user.setSalt(rs.getString(SQL_SALT));
123         } catch (SQLException sqle) {
124             LOG.error("SQL Exception: ", sqle);
125             throw sqle;
126         }
127         return user;
128     }
129
130     protected Users getUsers() throws StoreException {
131         Users users = new Users();
132         List<User> userList = new ArrayList<User>();
133         Connection conn = dbConnect();
134         Statement stmt = null;
135         String query = "SELECT * FROM users";
136         try {
137             stmt = conn.createStatement();
138             ResultSet rs = stmt.executeQuery(query);
139             while (rs.next()) {
140                 User user = rsToUser(rs);
141                 userList.add(user);
142             }
143             rs.close();
144             stmt.close();
145         } catch (SQLException s) {
146             throw new StoreException("SQL Exception");
147         } finally {
148             dbClose();
149         }
150         users.setUsers(userList);
151         return users;
152     }
153
154     protected Users getUsers(String username, String domain) throws StoreException {
155         LOG.debug("getUsers for: {} in domain {}", username, domain);
156
157         Users users = new Users();
158         List<User> userList = new ArrayList<User>();
159         Connection conn = dbConnect();
160         try {
161             PreparedStatement pstmt = conn
162                     .prepareStatement("SELECT * FROM USERS WHERE userid = ? ");
163             pstmt.setString(1, IDMStoreUtil.createUserid(username, domain));
164             LOG.debug("query string: {}", pstmt.toString());
165             ResultSet rs = pstmt.executeQuery();
166             while (rs.next()) {
167                 User user = rsToUser(rs);
168                 userList.add(user);
169             }
170             rs.close();
171             pstmt.close();
172         } catch (SQLException s) {
173             throw new StoreException("SQL Exception : " + s);
174         } finally {
175             dbClose();
176         }
177         users.setUsers(userList);
178         return users;
179     }
180
181     protected User getUser(String id) throws StoreException {
182         Connection conn = dbConnect();
183         try {
184             PreparedStatement pstmt = conn
185                     .prepareStatement("SELECT * FROM USERS WHERE userid = ? ");
186             pstmt.setString(1, id);
187             LOG.debug("query string: {}", pstmt.toString());
188             ResultSet rs = pstmt.executeQuery();
189             if (rs.next()) {
190                 User user = rsToUser(rs);
191                 rs.close();
192                 pstmt.close();
193                 return user;
194             } else {
195                 rs.close();
196                 pstmt.close();
197                 return null;
198             }
199         } catch (SQLException s) {
200             throw new StoreException("SQL Exception : " + s);
201         } finally {
202             dbClose();
203         }
204     }
205
206     protected User createUser(User user) throws StoreException {
207         Preconditions.checkNotNull(user);
208         Preconditions.checkNotNull(user.getName());
209         Preconditions.checkNotNull(user.getDomainid());
210
211         Connection conn = dbConnect();
212         try {
213             user.setSalt(SHA256Calculator.generateSALT());
214             String query = "insert into users (userid,domainid,name,email,password,description,enabled,salt) values(?,?,?,?,?,?,?,?)";
215             PreparedStatement statement = conn.prepareStatement(query);
216             user.setUserid(IDMStoreUtil.createUserid(user.getName(), user.getDomainid()));
217             statement.setString(1, user.getUserid());
218             statement.setString(2, user.getDomainid());
219             statement.setString(3, user.getName());
220             statement.setString(4, user.getEmail());
221             statement.setString(5, SHA256Calculator.getSHA256(user.getPassword(), user.getSalt()));
222             statement.setString(6, user.getDescription());
223             statement.setInt(7, user.isEnabled() ? 1 : 0);
224             statement.setString(8, user.getSalt());
225             int affectedRows = statement.executeUpdate();
226             if (affectedRows == 0) {
227                 throw new StoreException("Creating user failed, no rows affected.");
228             }
229             return user;
230         } catch (SQLException s) {
231             throw new StoreException("SQL Exception : " + s);
232         } finally {
233             dbClose();
234         }
235     }
236
237     protected User putUser(User user) throws StoreException {
238
239         User savedUser = this.getUser(user.getUserid());
240         if (savedUser == null) {
241             return null;
242         }
243
244         if (user.getDescription() != null) {
245             savedUser.setDescription(user.getDescription());
246         }
247         if (user.getName() != null) {
248             savedUser.setName(user.getName());
249         }
250         if (user.isEnabled() != null) {
251             savedUser.setEnabled(user.isEnabled());
252         }
253         if (user.getEmail() != null) {
254             savedUser.setEmail(user.getEmail());
255         }
256         if (user.getPassword() != null) {
257             savedUser.setPassword(SHA256Calculator.getSHA256(user.getPassword(), user.getSalt()));
258         }
259
260         Connection conn = dbConnect();
261         try {
262             String query = "UPDATE users SET email = ?, password = ?, description = ?, enabled = ? WHERE userid = ?";
263             PreparedStatement statement = conn.prepareStatement(query);
264             statement.setString(1, savedUser.getEmail());
265             statement.setString(2, savedUser.getPassword());
266             statement.setString(3, savedUser.getDescription());
267             statement.setInt(4, savedUser.isEnabled() ? 1 : 0);
268             statement.setString(5, savedUser.getUserid());
269             statement.executeUpdate();
270             statement.close();
271         } catch (SQLException s) {
272             throw new StoreException("SQL Exception : " + s);
273         } finally {
274             dbClose();
275         }
276
277         return savedUser;
278     }
279
280     protected User deleteUser(String userid) throws StoreException {
281         User savedUser = this.getUser(userid);
282         if (savedUser == null) {
283             return null;
284         }
285
286         Connection conn = dbConnect();
287         try {
288             String query = "DELETE FROM USERS WHERE userid = ?";
289             PreparedStatement statement = conn.prepareStatement(query);
290             statement.setString(1, savedUser.getUserid());
291             int deleteCount = statement.executeUpdate(query);
292             LOG.debug("deleted {} records", deleteCount);
293             statement.close();
294             return savedUser;
295         } catch (SQLException s) {
296             throw new StoreException("SQL Exception : " + s);
297         } finally {
298             dbClose();
299         }
300     }
301 }