Script - Security change at low level
This is an administrator script that should be used only when to propagate security changes under a folder which have a significant number of nodes is needed. These type of changes made from UI can take a lot of time to be propagated across the repository and this script does it much faster.
import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.Writer;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.text.MessageFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.sql.*;
import com.openkm.bean.Permission;import com.openkm.core.Config;
// PARAMETERSString LOG_FILE_NAME = "Security";int MAX_DEPTH = Integer.MAX_VALUE;String folder_UUID = "8ab2d963-0ced-4673-9991-54dd3d8b36b5";String[] roleName = {"ROLE_X","ROLE_Y"};int[] roleGrant = {Permission.READ, Permission.READ | Permission.WRITE};
public class FileLogger { public static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss,SSS"; public static String LEVEL_INFO = "INFO "; public static String LEVEL_WARN = "WARN "; public static String LEVEL_ERROR = "ERROR";
Writer cLogger = null;
public static void info(String baseName, String message) throws IOException { logWrite(baseName, LEVEL_INFO, message); }
public static void logWrite(String baseName, String level, String message) throws IOException { Writer sLogger = new FileWriter(getLogFile(baseName), true); sLogger.write(getLogEntry(level, message)); sLogger.flush(); sLogger.close(); } public static String getLogFile(String baseName) { String fileDate = new SimpleDateFormat("yyyyMMdd").format(new Date()); return Config.HOME_DIR + File.separator + baseName + "_" + fileDate + ".log"; }
public static void info(String message) throws IOException { cLogger.write(getLogEntry(LEVEL_INFO, message)); cLogger.flush(); }
public static void info(String baseName, String message, String param1, String param2) throws IOException { logWrite(baseName, LEVEL_INFO, message, param1, param2); }
public static void warm(String baseName, String message, String param1, String param2) throws IOException { logWrite(baseName, LEVEL_WARN, message, param1, param2); }
public static void error(String baseName, String message, String param1, String param2) throws IOException { logWrite(baseName, LEVEL_ERROR, message, param1, param2); }
public static void logWrite(String baseName, String level, String message, String param1, String param2) throws IOException { Writer sLogger = new FileWriter(getLogFile(baseName), true); sLogger.write(getLogEntry(level, message, param1, param2)); sLogger.flush(); sLogger.close(); }
public static String getLogEntry(String level, String message) { StringBuilder sb = new StringBuilder(); sb.append(new SimpleDateFormat(DATE_FORMAT).format(new Date())); sb.append(" "); sb.append(level); sb.append(" "); sb.append(message); sb.append("\n"); return sb.toString(); }
public static String getLogEntry(String level, String message, String param1, String param2) { Object[] params = {param1, param2}; StringBuilder sb = new StringBuilder(); sb.append(new SimpleDateFormat(DATE_FORMAT).format(new Date())); sb.append(" "); sb.append(level); sb.append(" "); sb.append(MessageFormat.format(message, params)); sb.append("\n"); return sb.toString(); }}
public void updateSecurity(Connection con, String UUID, int level) throws SQLException, IOException { FileLogger.info(LOG_FILE_NAME, "updateSecurity level:''{0}'' with UUID:''{1}''", String.valueOf(level), UUID); PreparedStatement ps = null; ResultSet rs = null; if (level == 0) { setParentNodeSecurity(con, UUID); removeAllChildrenNodeSecurity(con, UUID); setAllChildrenNodeSecurity(con, UUID); } if (level < MAX_DEPTH) { String sqlfindFolderChildren = "SELECT NBS_UUID FROM OKM_NODE_BASE WHERE NBS_PARENT=? and NBS_UUID in (SELECT NBS_UUID FROM OKM_NODE_FOLDER)"; try { ps = con.prepareStatement(sqlfindFolderChildren); ps.setString(1, UUID); rs = ps.executeQuery(); while (rs.next()) { String childUUID = rs.getString("NBS_UUID"); removeAllChildrenNodeSecurity(con, childUUID); setAllChildrenNodeSecurity(con, childUUID); updateSecurity(con, childUUID, level+1); } } catch (SQLException e) { FileLogger.error(LOG_FILE_NAME, "updateSecurity with UUID:''{0}'' con error ''{1}''", UUID, e.getMessage()); } finally { ps.close(); rs.close(); } }}
public void removeAllChildrenNodeSecurity(Connection con, String UUID) throws SQLException, IOException { PreparedStatement ps = null; String deleteChildrenNodeRoles = "DELETE FROM OKM_NODE_ROLE_PERMISSION where NRP_NODE in (SELECT NBS_UUID FROM OKM_NODE_BASE WHERE NBS_PARENT=?)"; String deleteChildrenNodeUsers = "DELETE FROM OKM_NODE_USER_PERMISSION where NUP_NODE in (SELECT NBS_UUID FROM OKM_NODE_BASE WHERE NBS_PARENT=?)"; try { ps = con.prepareStatement(deleteChildrenNodeRoles); ps.setString(1, UUID); ps.executeUpdate(); ps = con.prepareStatement(deleteChildrenNodeUsers); ps.setString(1, UUID); ps.executeUpdate(); con.commit(); } catch (SQLException e) { FileLogger.error(LOG_FILE_NAME, "removeAllChildrenNodeSecurity with UUID:''{0}'' con error ''{1}''", UUID, e.getMessage()); } finally { ps.close(); }}
public void setAllChildrenNodeSecurity(Connection con, String UUID) throws SQLException, IOException { PreparedStatement ps = null; ResultSet rs = null; String sqlfindAllChildren = "SELECT NBS_UUID FROM OKM_NODE_BASE WHERE NBS_PARENT=?"; String insertRoleSecurityChildren = "INSERT INTO OKM_NODE_ROLE_PERMISSION (NRP_NODE,NRP_PERMISSION, NRP_ROLE) VALUES (?,?,?)"; try { ps = con.prepareStatement(sqlfindAllChildren); ps.setString(1, UUID); rs = ps.executeQuery(); ps = con.prepareStatement(insertRoleSecurityChildren); while (rs.next()) { String childUUID = rs.getString("NBS_UUID"); for (int i=0; i<roleName.length; i++) { ps.setString(1,childUUID); ps.setInt(2, roleGrant[i]); ps.setString(3,roleName[i]); ps.addBatch(); } } ps.executeBatch(); con.commit(); } catch (SQLException e) { FileLogger.error(LOG_FILE_NAME, "removeAllChildrenNodeSecurity with UUID:''{0}'' con error ''{1}''", UUID, e.getMessage()); } finally { ps.close(); rs.close(); }}
public void setParentNodeSecurity(Connection con, String UUID) throws SQLException, IOException { PreparedStatement ps = null; String deleteChildrenNodeRoles = "DELETE FROM OKM_NODE_ROLE_PERMISSION where NRP_NODE =?"; String deleteChildrenNodeUsers = "DELETE FROM OKM_NODE_USER_PERMISSION where NUP_NODE =?"; String insertRoleSecurityChildren = "INSERT INTO OKM_NODE_ROLE_PERMISSION (NRP_NODE,NRP_PERMISSION, NRP_ROLE) VALUES (?,?,?)"; try { ps = con.prepareStatement(deleteChildrenNodeRoles); ps.setString(1, UUID); ps.executeUpdate(); ps = con.prepareStatement(deleteChildrenNodeUsers); ps.setString(1, UUID); ps.executeUpdate(); ps = con.prepareStatement(insertRoleSecurityChildren); for (int i=0; i<roleName.length; i++) { ps.setString(1,UUID); ps.setInt(2, roleGrant[i]); ps.setString(3,roleName[i]); ps.addBatch(); } ps.executeBatch(); con.commit(); } catch (SQLException e) { FileLogger.error(LOG_FILE_NAME, "setParentNodeSecurity with UUID:''{0}'' con error ''{1}''", UUID, e.getMessage()); } finally { ps.close(); }}
FileLogger.info(LOG_FILE_NAME, "**** Security change started ****");Class.forName("com.mysql.jdbc.Driver");Connection con = null;con = DriverManager.getConnection("jdbc:mysql://localhost:3306/okmdb","openkm", "*secret*");con.setAutoCommit(false);updateSecurity(con, folder_UUID, 0);con.close();FileLogger.info(LOG_FILE_NAME, "**** Security change ended ****");Images
Section titled “Images”Initial security status
Section titled “Initial security status”
UUID of the folder
Section titled “UUID of the folder”
Execution
Section titled “Execution”Change script parameters by your owns.
Consider take a look at file log to see progress of the process and check for errors.

Rebuild Lucene indexes
Section titled “Rebuild Lucene indexes”Caused by changes of the security at a database level, it is necessary for maintaining integrity with search engine, reindex Lucene indexes.


Security changed applied
Section titled “Security changed applied”