c8730887c225eff166ea1166dede2a3d23071f36
[aaa.git] / aaa-idm-store-h2 / src / main / java / org / opendaylight / aaa / datastore / h2 / GrantStore.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
9 package org.opendaylight.aaa.datastore.h2;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
13 import java.sql.ResultSet;
14 import java.sql.SQLException;
15 import java.sql.Statement;
16 import org.apache.commons.text.StringEscapeUtils;
17 import org.opendaylight.aaa.api.IDMStoreUtil;
18 import org.opendaylight.aaa.api.model.Grant;
19 import org.opendaylight.aaa.api.model.Grants;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24  * Grant store.
25  *
26  * @author peter.mellquist@hp.com
27  */
28 final class GrantStore extends AbstractStore<Grant> {
29     private static final Logger LOG = LoggerFactory.getLogger(GrantStore.class);
30
31     static final String TABLE = "AAA_GRANTS";
32
33     static {
34         SQLTable.GRANT.verifyTable(TABLE);
35     }
36
37     // FIXME: javadoc
38     static final String COL_ID = "grantid";
39
40     // FIXME: javadoc
41     // FIXME: 'tenant' vs 'domain' ?
42     @VisibleForTesting
43     static final String COL_TENANTID = "domainid";
44
45     // FIXME: javadoc
46     @VisibleForTesting
47     static final String COL_USERID = "userid";
48     // FIXME: javadoc
49     @VisibleForTesting
50     static final String COL_ROLEID = "roleid";
51
52     GrantStore(final ConnectionProvider dbConnectionFactory) {
53         super(dbConnectionFactory, TABLE);
54     }
55
56     @Override
57     void createTable(final Statement stmt) throws SQLException {
58         stmt.executeUpdate("CREATE TABLE " + TABLE + " ("
59             + COL_ID       + " VARCHAR(128) PRIMARY KEY, "
60             // FIXME: foreign key to DomainStore.COL_ID?
61             + COL_TENANTID + " VARCHAR(128) NOT NULL, "
62             // FIXME: foreign key to UserStore.COL_ID?
63             + COL_USERID   + " VARCHAR(128) NOT NULL, "
64             // FIXME: foreign key to RoleStore.COL_ID?
65             + COL_ROLEID   + " VARCHAR(128) NOT NULL)");
66     }
67
68     @Override
69     void cleanTable(final Statement stmt) throws SQLException {
70         stmt.execute("DELETE FROM " + TABLE);
71     }
72
73     @Override
74     protected Grant fromResultSet(final ResultSet rs) throws SQLException {
75         Grant grant = new Grant();
76         try {
77             grant.setGrantid(rs.getString(COL_ID));
78             grant.setDomainid(rs.getString(COL_TENANTID));
79             grant.setUserid(rs.getString(COL_USERID));
80             grant.setRoleid(rs.getString(COL_ROLEID));
81         } catch (SQLException sqle) {
82             LOG.error("SQL Exception: ", sqle);
83             throw sqle;
84         }
85         return grant;
86     }
87
88     Grants getGrants(final String domainId, final String userId) throws StoreException {
89         final Grants grants;
90         try (var conn = dbConnect();
91              var stmt = conn.prepareStatement("SELECT * FROM " + TABLE
92                  + " WHERE " + COL_TENANTID + " = ? AND " + COL_USERID + " = ?")) {
93             stmt.setString(1, domainId);
94             stmt.setString(2, userId);
95             LOG.debug("getGrants() request: {}", stmt);
96
97             grants = new Grants();
98             grants.setGrants(listFromStatement(stmt));
99         } catch (SQLException e) {
100             throw new StoreException("SQL Exception", e);
101         }
102         return grants;
103     }
104
105     Grants getGrants(final String userid) throws StoreException {
106         final Grants grants;
107         try (var conn = dbConnect();
108              var stmt = conn.prepareStatement("SELECT * FROM " + TABLE + " WHERE " + COL_USERID + " = ?")) {
109             stmt.setString(1, userid);
110             LOG.debug("getGrants() request: {}", stmt);
111
112             grants = new Grants();
113             grants.setGrants(listFromStatement(stmt));
114         } catch (SQLException e) {
115             throw new StoreException("SQL Exception", e);
116         }
117         return grants;
118     }
119
120     Grant getGrant(final String id) throws StoreException {
121         try (var conn = dbConnect();
122              var stmt = conn.prepareStatement("SELECT * FROM " + TABLE + " WHERE " + COL_ID + " = ?")) {
123             stmt.setString(1, id);
124             LOG.debug("getGrant() request: {}", stmt);
125
126             return firstFromStatement(stmt);
127         } catch (SQLException e) {
128             throw new StoreException("SQL Exception", e);
129         }
130     }
131
132     // FIXME: seems to be unused
133     Grant getGrant(final String did, final String uid, final String rid) throws StoreException {
134         try (var conn = dbConnect();
135              var stmt = conn.prepareStatement("SELECT * FROM " + TABLE
136                  + " WHERE " + COL_TENANTID + " = ? AND " + COL_USERID + " = ? AND " + COL_ROLEID + " = ?")) {
137             stmt.setString(1, did);
138             stmt.setString(2, uid);
139             stmt.setString(3, rid);
140             LOG.debug("getGrant() request: {}", stmt);
141
142             return firstFromStatement(stmt);
143         } catch (SQLException e) {
144             throw new StoreException("SQL Exception", e);
145         }
146     }
147
148     Grant createGrant(final Grant grant) throws StoreException {
149         try (var conn = dbConnect();
150              var stmt = conn.prepareStatement("INSERT INTO " + TABLE + " ("
151                  + COL_ID + ", " + COL_TENANTID + ", " + COL_USERID + ", " + COL_ROLEID + ") VALUES (?, ?, ?, ?)")) {
152             stmt.setString(1, IDMStoreUtil.createGrantid(grant.getUserid(), grant.getDomainid(), grant.getRoleid()));
153             stmt.setString(2, grant.getDomainid());
154             stmt.setString(3, grant.getUserid());
155             stmt.setString(4, grant.getRoleid());
156             LOG.debug("createGrant() request: {}", stmt);
157
158             if (stmt.executeUpdate() == 0) {
159                 throw new StoreException("Creating grant failed, no rows affected.");
160             }
161             grant.setGrantid(IDMStoreUtil.createGrantid(grant.getUserid(), grant.getDomainid(), grant.getRoleid()));
162             return grant;
163         } catch (SQLException e) {
164             throw new StoreException("SQL Exception", e);
165         }
166     }
167
168     @SuppressFBWarnings(value = "SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE", justification = "Weird original code")
169     Grant deleteGrant(final String grantid) throws StoreException {
170         final String escaped = StringEscapeUtils.escapeHtml4(grantid);
171         final var savedGrant = getGrant(escaped);
172         if (savedGrant == null) {
173             return null;
174         }
175
176         try (var conn = dbConnect();
177              var stmt = conn.createStatement()) {
178             // FIXME: prepare statement instead
179             final String query = String.format("DELETE FROM " + TABLE +  " WHERE " + COL_ID + " = '%s'", escaped);
180             LOG.debug("deleteGrant() request: {}", query);
181
182             int deleteCount = stmt.executeUpdate(query);
183             LOG.debug("deleted {} records", deleteCount);
184             return savedGrant;
185         } catch (SQLException e) {
186             throw new StoreException("SQL Exception", e);
187         }
188     }
189 }