Use prepareStatement() in UserStore.deleteUser()
[aaa.git] / aaa-idm-store-h2 / src / main / java / org / opendaylight / aaa / datastore / h2 / UserStore.java
1 /*
2  * Copyright (c) 2014, 2017 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 package org.opendaylight.aaa.datastore.h2;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.sql.Connection;
13 import java.sql.PreparedStatement;
14 import java.sql.ResultSet;
15 import java.sql.SQLException;
16 import java.util.Objects;
17 import org.opendaylight.aaa.api.IDMStoreUtil;
18 import org.opendaylight.aaa.api.model.User;
19 import org.opendaylight.aaa.api.model.Users;
20 import org.opendaylight.aaa.api.password.service.PasswordHash;
21 import org.opendaylight.aaa.api.password.service.PasswordHashService;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Store for users.
27  *
28  * @author peter.mellquist@hp.com
29  *
30  */
31 public class UserStore extends AbstractStore<User> {
32     private static final Logger LOG = LoggerFactory.getLogger(UserStore.class);
33
34     public static final String SQL_ID = "userid";
35     public static final String SQL_DOMAIN_ID = "domainid";
36     public static final String SQL_NAME = "name";
37     public static final String SQL_EMAIL = "email";
38     public static final String SQL_PASSWORD = "password";
39     public static final String SQL_DESCR = "description";
40     public static final String SQL_ENABLED = "enabled";
41     public static final String SQL_SALT = "salt";
42     private static final String TABLE_NAME = "USERS";
43
44     private final PasswordHashService passwordService;
45
46     public UserStore(final ConnectionProvider dbConnectionFactory, final PasswordHashService passwordService) {
47         super(dbConnectionFactory, TABLE_NAME);
48         this.passwordService = Objects.requireNonNull(passwordService);
49     }
50
51     @Override
52     protected String getTableCreationStatement() {
53         return "CREATE TABLE users " + "(userid    VARCHAR(128) PRIMARY KEY,"
54                 + "name       VARCHAR(128)      NOT NULL, " + "domainid   VARCHAR(128)      NOT NULL, "
55                 + "email      VARCHAR(128)      NOT NULL, " + "password   VARCHAR(128)      NOT NULL, "
56                 + "description VARCHAR(128)     NOT NULL, " + "salt        VARCHAR(128)      NOT NULL, "
57                 + "enabled     INTEGER          NOT NULL)";
58     }
59
60     @Override
61     protected User fromResultSet(final ResultSet rs) throws SQLException {
62         User user = new User();
63         try {
64             user.setUserid(rs.getString(SQL_ID));
65             user.setDomainid(rs.getString(SQL_DOMAIN_ID));
66             user.setName(rs.getString(SQL_NAME));
67             user.setEmail(rs.getString(SQL_EMAIL));
68             user.setPassword(rs.getString(SQL_PASSWORD));
69             user.setDescription(rs.getString(SQL_DESCR));
70             user.setEnabled(rs.getInt(SQL_ENABLED) == 1);
71             user.setSalt(rs.getString(SQL_SALT));
72         } catch (SQLException sqle) {
73             LOG.error("SQL Exception: ", sqle);
74             throw sqle;
75         }
76         return user;
77     }
78
79     public Users getUsers() throws StoreException {
80         Users users = new Users();
81         users.setUsers(listAll());
82         return users;
83     }
84
85     protected Users getUsers(final String username, final String domain) throws StoreException {
86         LOG.debug("getUsers for: {} in domain {}", username, domain);
87
88         Users users = new Users();
89         try (Connection conn = dbConnect();
90                 PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM USERS WHERE userid = ? ")) {
91             pstmt.setString(1, IDMStoreUtil.createUserid(username, domain));
92             LOG.debug("query string: {}", pstmt);
93             users.setUsers(listFromStatement(pstmt));
94         } catch (SQLException s) {
95             throw new StoreException("SQL Exception : " + s);
96         }
97         return users;
98     }
99
100     public User getUser(final String id) throws StoreException {
101         try (Connection conn = dbConnect();
102                 PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM USERS WHERE userid = ? ")) {
103             pstmt.setString(1, id);
104             LOG.debug("query string: {}", pstmt);
105             return firstFromStatement(pstmt);
106         } catch (SQLException s) {
107             throw new StoreException("SQL Exception : " + s);
108         }
109     }
110
111     protected User createUser(final User user) throws StoreException {
112         requireNonNull(user);
113         requireNonNull(user.getName());
114         requireNonNull(user.getDomainid());
115
116         final PasswordHash passwordHash = passwordService.getPasswordHash(user.getPassword());
117         user.setSalt(passwordHash.getSalt());
118         String query =
119                 "insert into users"
120                 + " (userid,domainid,name,email,password,description,enabled,salt) values(?,?,?,?,?,?,?,?)";
121         try (Connection conn = dbConnect(); PreparedStatement statement = conn.prepareStatement(query)) {
122             user.setUserid(IDMStoreUtil.createUserid(user.getName(), user.getDomainid()));
123             statement.setString(1, user.getUserid());
124             statement.setString(2, user.getDomainid());
125             statement.setString(3, user.getName());
126             statement.setString(4, user.getEmail());
127             statement.setString(5, passwordHash.getHashedPassword());
128             statement.setString(6, user.getDescription());
129             statement.setInt(7, user.isEnabled() ? 1 : 0);
130             statement.setString(8, user.getSalt());
131             int affectedRows = statement.executeUpdate();
132             if (affectedRows == 0) {
133                 throw new StoreException("Creating user failed, no rows affected.");
134             }
135             return user;
136         } catch (SQLException s) {
137             throw new StoreException("SQL Exception : " + s);
138         }
139     }
140
141     public User putUser(final User user) throws StoreException {
142
143         User savedUser = getUser(user.getUserid());
144         if (savedUser == null) {
145             return null;
146         }
147
148         if (user.getDescription() != null) {
149             savedUser.setDescription(user.getDescription());
150         }
151         if (user.getName() != null) {
152             savedUser.setName(user.getName());
153         }
154         if (user.isEnabled() != null) {
155             savedUser.setEnabled(user.isEnabled());
156         }
157         if (user.getEmail() != null) {
158             savedUser.setEmail(user.getEmail());
159         }
160         if (user.getPassword() != null) {
161             // If a new salt is provided, use it. Otherwise, derive salt from
162             // existing.
163             String salt = user.getSalt();
164             if (salt == null) {
165                 salt = savedUser.getSalt();
166             }
167             final PasswordHash passwordHash = passwordService.getPasswordHash(user.getPassword(), salt);
168             savedUser.setPassword(passwordHash.getHashedPassword());
169         }
170
171         String query = "UPDATE users SET email = ?, password = ?, description = ?, enabled = ? WHERE userid = ?";
172         try (Connection conn = dbConnect(); PreparedStatement statement = conn.prepareStatement(query)) {
173             statement.setString(1, savedUser.getEmail());
174             statement.setString(2, savedUser.getPassword());
175             statement.setString(3, savedUser.getDescription());
176             statement.setInt(4, savedUser.isEnabled() ? 1 : 0);
177             statement.setString(5, savedUser.getUserid());
178             statement.executeUpdate();
179         } catch (SQLException s) {
180             throw new StoreException("SQL Exception : " + s);
181         }
182
183         return savedUser;
184     }
185
186     protected User deleteUser(final String userid) throws StoreException {
187         User savedUser = getUser(userid);
188         if (savedUser == null) {
189             return null;
190         }
191
192         String query = "DELETE FROM USERS WHERE userid = ?";
193         try (Connection conn = dbConnect(); PreparedStatement statement = conn.prepareStatement(query)) {
194             statement.setString(1, userid);
195             int deleteCount = statement.executeUpdate();
196             LOG.debug("deleted {} records", deleteCount);
197             return savedUser;
198         } catch (SQLException s) {
199             throw new StoreException("SQL Exception : " + s);
200         }
201     }
202 }