AccountExtUtil.java
/*
** Module : AccountExtUtil.java
** Abstract : Wrapper class for account ext methods (moved from SecurityManager).
**
** Copyright (c) 2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- ------------------------------------Description-------------------------------------------
** 001 GBB 20230825 Initial version.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.security;
import com.goldencode.p2j.directory.*;
/**
* Wrapper class for account ext methods.
* <p>
* Using it through {@link SecurityManager#accountExt} allows resetting SecurityManager instance.
*/
public class AccountExtUtil
{
/** SecurityManager instance. */
private final SecurityManager sm;
/**
* Package-private constructor.
*
* @param sm
* SecurityManager instance
*/
AccountExtUtil(SecurityManager sm)
{
this.sm = sm;
}
/**
* Gets the named piece of account extension data of type int for the
* current user account.
*
* @param extName
* account extension name
*
* @return extension value wrapped into <code>Integer</code> or
* <code>null</code> if no such extension exists.
*/
public Integer getExtInteger(String extName)
{
return getExtInteger(extName, sm.getUserId());
}
/**
* Gets the named piece of account extension data of type boolean for the
* current user account.
*
* @param extName
* account extension name
*
* @return extension value wrapped into <code>Boolean</code> or
* <code>null</code> if no such extension exists.
*/
public Boolean getExtBoolean(String extName)
{
return getExtBoolean(extName, sm.getUserId());
}
/**
* Gets the named piece of account extension data of type String for the
* current user account.
*
* @param extName
* account extension name
*
* @return extension value or
* <code>null</code> if no such extension exists.
*/
public String getExtString(String extName)
{
return getExtString(extName, sm.getUserId());
}
/**
* Gets the named piece of account extension data of type String for the
* current user account.
*
* @param extName
* account extension name
*
* @return extension value or
* <code>null</code> if no such extension exists.
*/
public DateValue getExtDate(String extName)
{
return getExtDate(extName, sm.getUserId());
}
/**
* Gets the named piece of account extension data of type byte[] for the
* current user account.
*
* @param extName
* account extension name
*
* @return extension value or
* <code>null</code> if no such extension exists.
*/
public byte[] getExtBytes(String extName)
{
return getExtBytes(extName, sm.getUserId());
}
/**
* Gets the named piece of account extension data of type int for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
*
* @return extension value wrapped into <code>Integer</code> or
* <code>null</code> if no such extension exists.
*/
public Integer getExtInteger(String extName, String subjectId)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// get the target directory object's "value" attribute of type Integer
Integer value = ds.getNodeInteger(path + "/" + extName, "value");
// deactivate directory services
ds.unbind();
return value;
}
/**
* Gets the named piece of account extension data of type boolean for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
*
* @return extension value wrapped into <code>Boolean</code> or
* <code>null</code> if no such extension exists.
*/
public Boolean getExtBoolean(String extName, String subjectId)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// get the target directory object's "value" attribute of type Integer
Boolean value = ds.getNodeBoolean(path + "/" + extName, "value");
// deactivate directory services
ds.unbind();
return value;
}
/**
* Gets the named piece of account extension data of type String for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
*
* @return extension value or
* <code>null</code> if no such extension exists.
*/
public String getExtString(String extName, String subjectId)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// get the target directory object's "value" attribute of type Integer
String value = ds.getNodeString(path + "/" + extName, "value");
// deactivate directory services
ds.unbind();
return value;
}
/**
* Gets the named piece of account extension data of type date for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
*
* @return extension value or
* <code>null</code> if no such extension exists.
*/
public DateValue getExtDate(String extName, String subjectId)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// get the target directory object's "value" attribute of type Integer
DateValue value = ds.getNodeDate(path + "/" + extName, "value");
// deactivate directory services
ds.unbind();
return value;
}
/**
* Gets the named piece of account extension data of type byte[] for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
*
* @return extension value or
* <code>null</code> if no such extension exists.
*/
public byte[] getExtBytes(String extName, String subjectId)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// get the target directory object's "value" attribute of type Integer
byte[] value = ds.getNodeByteArray(path + "/" + extName, "value");
// deactivate directory services
ds.unbind();
return value;
}
/**
* Sets the named piece of account extension data of type int for the
* current user account.
*
* @param extName
* account extension name
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtInteger(String extName, int value)
{
return setExtInteger(extName, sm.getUserId(), value);
}
/**
* Sets the named piece of account extension data of type boolean for the
* current user account.
*
* @param extName
* account extension name
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtBoolean(String extName, boolean value)
{
return setExtBoolean(extName, sm.getUserId(), value);
}
/**
* Sets the named piece of account extension data of type String for the
* current user account.
*
* @param extName
* account extension name
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtString(String extName, String value)
{
return setExtString(extName, sm.getUserId(), value);
}
/**
* Sets the named piece of account extension data of type byte[] for the
* current user account.
*
* @param extName
* account extension name
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtBytes(String extName, byte[] value)
{
return setExtBytes(extName, sm.getUserId(), value);
}
/**
* Sets the named piece of account extension data of type int for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtInteger(String extName, String subjectId, int value)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return false;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return false;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return false;
if (!ds.bind())
return false;
// open an editing batch
if (!ds.openBatch(path))
{
ds.unbind();
return false;
}
// set the target directory object's "value" attribute of type Integer
boolean rc = ds.setNodeInteger(path + "/" + extName, "value", value);
// close the batch
boolean brc = ds.closeBatch(rc);
// deactivate directory services
ds.unbind();
if (!brc)
return false;
return rc;
}
/**
* Sets the named piece of account extension data of type boolean for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtBoolean(String extName, String subjectId, boolean value)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return false;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return false;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return false;
if (!ds.bind())
return false;
// open an editing batch
if (!ds.openBatch(path))
{
ds.unbind();
return false;
}
// set the target directory object's "value" attribute of type Integer
boolean rc = ds.setNodeBoolean(path + "/" + extName, "value", value);
// close the batch
if (!ds.closeBatch(true))
{
ds.unbind();
return false;
}
// deactivate directory services
ds.unbind();
return rc;
}
/**
* Sets the named piece of account extension data of type String for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtString(String extName, String subjectId, String value)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return false;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return false;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return false;
if (!ds.bind())
return false;
// open an editing batch
if (!ds.openBatch(path))
{
ds.unbind();
return false;
}
// set the target directory object's "value" attribute of type Integer
boolean rc = ds.setNodeString(path + "/" + extName, "value", value);
// close the batch
if (!ds.closeBatch(true))
{
ds.unbind();
return false;
}
// deactivate directory services
ds.unbind();
return rc;
}
/**
* Sets the named piece of account extension data of type byte[] for the
* specified account.
*
* @param extName
* account extension name
* @param subjectId
* subject ID
* @param value
* new value for the account extension
*
* @return <code>true</code> if successfully set the value
*/
public boolean setExtBytes(String extName, String subjectId, byte[] value)
{
// check the access rights
if (sm.getUserId().compareToIgnoreCase(subjectId) != 0)
{
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return false;
}
String path = locateExtensionPath(subjectId);
if (path == null)
return false;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return false;
if (!ds.bind())
return false;
// open an editing batch
if (!ds.openBatch(path))
{
ds.unbind();
return false;
}
// set the target directory object's "value" attribute of type Integer
boolean rc = ds.setNodeByteArray(path + "/" + extName, "value", value);
// close the batch
if (!ds.closeBatch(true))
{
ds.unbind();
return false;
}
// deactivate directory services
ds.unbind();
return rc;
}
/**
* Gets the user ID of a user having a matching value in a specified
* named account extension of integer type.
*
* @param extName
* account extension name
*
* @param extValue
* extension value
*
* @return user ID or <code>null</code> if no such extension exists.
*/
public String getIdByExtInteger(String extName, int extValue)
{
// check the access rights
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
// get all user account IDs
String[] uid = sm.getAllUsers();
String retValue = null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// try each user ID
String path = null;
Integer value = null;
for (int i = 0; i < uid.length; i++)
{
path = locateExtensionPath(uid[i]);
if (path == null)
continue;
// get the directory object's "value" attribute of type Integer
value = ds.getNodeInteger(path + "/" + extName, "value");
if (value == null)
{
continue;
}
if (value == extValue)
{
retValue = uid[i];
break;
}
}
// deactivate directory services
ds.unbind();
return retValue;
}
/**
* Gets the user ID of a user having a matching value in a specified
* named account extension of string type.
*
* @param extName
* account extension name
*
* @param extValue
* extension value
*
* @param cs
* case sensitivity for comparison. <code>true</code> means
* case-sensitive comparison.
*
* @return user ID or <code>null</code> if no such extension exists.
*/
public String getIdByExtString(String extName, String extValue, boolean cs)
{
// check the access rights
SystemResource sr = (SystemResource) sm.getPluginInstance("system");
boolean decision = sr.checkExtensionsAccess();
if (!decision)
return null;
// get all user account IDs
String[] uid = sm.getAllUsers();
String retValue = null;
// activate directory services
DirectoryService ds = DirectoryService.getInstance();
if (ds == null)
return null;
if (!ds.bind())
return null;
// try each user ID
String path = null;
String value = null;
boolean comp = false;
for (int i = 0; i < uid.length; i++)
{
path = locateExtensionPath(uid[i]);
if (path == null)
continue;
// get the target directory object's "value" attribute of type Integer
value = ds.getNodeString(path + "/" + extName, "value");
if (value == null)
{
continue;
}
// compare extension value accounting for requested case sensitivity
if (cs)
comp = value.equals(extValue);
else
comp = value.compareToIgnoreCase(extValue) == 0;
if (comp)
{
retValue = uid[i];
break;
}
}
// deactivate directory services
ds.unbind();
return retValue;
}
/**
* Locates the account extension directory path for the specified user ID.
*
* @param uid
* user ID
*
* @return directory path to the account extensions
*/
private String locateExtensionPath(String uid)
{
// Pick up the generation of security cache
SecurityContextStack ctxs = SecurityContextStack.getContext();
SecurityContext ctx = ctxs.getEffectiveContext();
SecurityCache sc = ctx.getCache();
// find the account
Account acc = sc.getAccountById(uid);
if (acc == null)
return null;
// figure out account type and extension path
switch (acc.getAccountType())
{
case Account.ACC_USER:
return "/security/accounts/users/" + uid;
case Account.ACC_GROUP:
return null;
case Account.ACC_PROCESS:
return "/security/accounts/processes/" + uid;
}
return null;
}
}