[ 
https://issues.apache.org/jira/browse/KNOX-3426?focusedWorklogId=1038576&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1038576
 ]

ASF GitHub Bot logged work on KNOX-3426:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 28/Aug/26 22:35
            Start Date: 28/Aug/26 22:35
    Worklog Time Spent: 10m 
      Work Description: lmccay commented on code in PR #1361:
URL: https://github.com/apache/knox/pull/1361#discussion_r3884471319


##########
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:
   Fair suggestion.





Issue Time Tracking
-------------------

    Worklog Id:     (was: 1038576)
    Time Spent: 50m  (was: 40m)

> 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
>            Priority: Major
>          Time Spent: 50m
>  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)

Reply via email to