[
https://issues.apache.org/jira/browse/KNOX-3426?focusedWorklogId=1038943&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1038943
]
ASF GitHub Bot logged work on KNOX-3426:
----------------------------------------
Author: ASF GitHub Bot
Created on: 31/Aug/26 22:48
Start Date: 31/Aug/26 22:48
Worklog Time Spent: 10m
Work Description: hsheinblatt commented on code in PR #1361:
URL: https://github.com/apache/knox/pull/1361#discussion_r3899099573
##########
gateway-server/src/main/java/org/apache/knox/gateway/services/knoxidf/delegation/DelegationPolicyDatabase.java:
##########
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package org.apache.knox.gateway.services.knoxidf.delegation;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.knox.gateway.database.DatabaseType;
+import org.apache.knox.gateway.database.JDBCUtils;
+import org.apache.knox.gateway.database.KnoxDatabase;
+
+import javax.sql.DataSource;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * JDBC helper for the five DELEGATION_POLICIES tables.
+ * All SQL uses {@link PreparedStatement} with {@code ?} parameters only.
+ * Each public method manages its own {@link Connection} and, for multi-table
writes,
+ * its own transaction boundaries (setAutoCommit / commit / rollback).
+ */
+class DelegationPolicyDatabase extends KnoxDatabase {
+
+ static final String CORE_TABLE = "DELEGATION_POLICIES";
+
+ private static final String INSERT_REGISTRATION_SQL =
+ "INSERT INTO " + CORE_TABLE
+ + " (registration_id, actor_authority, actor_id, name, status,
token_ttl_sec, "
+ + "description, created_by, created_at, updated_at,
allow_headless_exchange) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ private static final String UPDATE_CORE_SQL =
+ "UPDATE " + CORE_TABLE + " SET "
+ + "actor_authority = ?, actor_id = ?, name = ?, status = ?,
token_ttl_sec = ?, "
+ + "description = ?, created_by = ?, created_at = ?, updated_at = ?, "
+ + "allow_headless_exchange = ? "
+ + "WHERE registration_id = ?";
+
+ private static final String DELETE_REGISTRATION_SQL =
+ "DELETE FROM " + CORE_TABLE + " WHERE registration_id = ?";
+
+ private static final String SELECT_BY_ID_SQL =
+ "SELECT registration_id, actor_authority, actor_id, name, status,
token_ttl_sec, "
+ + "description, created_by, created_at, updated_at,
allow_headless_exchange "
+ + "FROM " + CORE_TABLE + " WHERE registration_id = ?";
+
+ private static final String SELECT_BY_ACTOR_SQL =
+ "SELECT registration_id, actor_authority, actor_id, name, status,
token_ttl_sec, "
+ + "description, created_by, created_at, updated_at,
allow_headless_exchange "
+ + "FROM " + CORE_TABLE + " WHERE actor_authority = ? AND actor_id =
?";
+
+ private static final String SELECT_ALL_BASE_SQL =
+ "SELECT registration_id, actor_authority, actor_id, name, status,
token_ttl_sec, "
+ + "description, created_by, created_at, updated_at,
allow_headless_exchange "
+ + "FROM " + CORE_TABLE;
+
+ // Built at construction time with limit+1 baked in as an integer literal
(Derby does not
+ // support ? parameters in FETCH FIRST n ROWS ONLY). Fetching one extra row
lets selectAll()
+ // detect truncation without a second COUNT query.
+ private final int listMaxTotal;
+ private final int listMaxPerAuthority;
+ private final String selectAllSql;
+ private final String selectAllFilteredSql;
+
+ private static final String INSERT_USER_SQL =
+ "INSERT INTO DELEGATION_POLICY_USERS (registration_id, username) VALUES
(?, ?)";
+
+ private static final String INSERT_GROUP_SQL =
+ "INSERT INTO DELEGATION_POLICY_GROUPS (registration_id, group_name)
VALUES (?, ?)";
+
+ private static final String INSERT_RESOURCE_SQL =
+ "INSERT INTO DELEGATION_POLICY_RESOURCES (registration_id, resource_uri)
VALUES (?, ?)";
+
+ private static final String INSERT_SCOPE_SQL =
+ "INSERT INTO DELEGATION_POLICY_RESOURCE_SCOPES (registration_id,
resource_uri, scope) VALUES (?, ?, ?)";
+
+ private static final String SELECT_USERS_SQL =
+ "SELECT username FROM DELEGATION_POLICY_USERS WHERE registration_id = ?";
+
+ private static final String SELECT_GROUPS_SQL =
+ "SELECT group_name FROM DELEGATION_POLICY_GROUPS WHERE registration_id =
?";
+
+ private static final String SELECT_RESOURCES_SQL =
+ "SELECT resource_uri FROM DELEGATION_POLICY_RESOURCES WHERE
registration_id = ?";
+
+ private static final String SELECT_SCOPES_SQL =
+ "SELECT scope FROM DELEGATION_POLICY_RESOURCE_SCOPES WHERE
registration_id = ? AND resource_uri = ?";
+
+ private static final String DELETE_USERS_SQL =
+ "DELETE FROM DELEGATION_POLICY_USERS WHERE registration_id = ?";
+
+ private static final String DELETE_GROUPS_SQL =
+ "DELETE FROM DELEGATION_POLICY_GROUPS WHERE registration_id = ?";
+
+ private static final String DELETE_RESOURCES_SQL =
+ "DELETE FROM DELEGATION_POLICY_RESOURCES WHERE registration_id = ?";
+
+ DelegationPolicyDatabase(DataSource dataSource, String dbType, int
listMaxTotal, int listMaxPerAuthority) throws Exception {
+ super(dataSource);
+ this.listMaxTotal = listMaxTotal;
+ this.listMaxPerAuthority = listMaxPerAuthority;
+ this.selectAllSql = SELECT_ALL_BASE_SQL + " FETCH FIRST " + (listMaxTotal
+ 1) + " ROWS ONLY";
+ this.selectAllFilteredSql = SELECT_ALL_BASE_SQL + " WHERE actor_authority
= ? FETCH FIRST " + (listMaxPerAuthority + 1) + " ROWS ONLY";
+ final DatabaseType databaseType = DatabaseType.fromString(dbType);
+
createDelegationTablesIfNotExists(databaseType.delegationPolicyTablesSql());
+ }
+
+ /**
+ * Multi-statement DDL runner: checks if DELEGATION_POLICIES exists, then
strips SQL line
+ * comments, splits on {@code ;}, and executes each non-empty statement
individually.
+ * {@link JDBCUtils#createTableFromSQL} handles only single statements;
delegation needs five.
+ * Comment stripping must happen before the split because the ASF license
header contains a
+ * semicolon inside a {@code --} comment line, which would otherwise produce
a spurious token.
+ */
+ private void createDelegationTablesIfNotExists(String sqlFileName) throws
Exception {
+ if (!JDBCUtils.tableExists(CORE_TABLE, dataSource)) {
+ try (InputStream is =
getClass().getClassLoader().getResourceAsStream(sqlFileName);
+ Connection connection = dataSource.getConnection()) {
+ final String script = IOUtils.toString(is, UTF_8);
+ final StringBuilder stripped = new StringBuilder();
Review Comment:
This one is really hard to test, and a bit unlikely to occur. This is a
private method a few layers down in init. In order to get to this error path,
we'd need a databasetype that succeeded lookup but was missing a valid sql
resource. I can add this protection, but then I'll skip the unit test for it.
Ideally one of the layers leading to it should fail at build time not runtime
if there is a problem.
Issue Time Tracking
-------------------
Worklog Id: (was: 1038943)
Time Spent: 2h 10m (was: 2h)
> Delegation policy schema and JDBC implementation
> ------------------------------------------------
>
> Key: KNOX-3426
> URL: https://issues.apache.org/jira/browse/KNOX-3426
> Project: Apache Knox
> Issue Type: Task
> Components: JWT
> Reporter: Harrison Sheinblatt
> Assignee: Harrison Sheinblatt
> Priority: Major
> Time Spent: 2h 10m
> Remaining Estimate: 0h
>
> Persistent storage for delegation policies, with a service interface and JDBC
> implementation. After these tasks, delegation policies can be stored and
> retrieved.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)