Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright 2014 Internet2
*
* Licensed 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
/*
Copyright (C) 2004-2007 University Corporation for Advanced Internet Development, Inc.
Copyright (C) 2004-2007 The University Of Chicago
Licensed 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
http://www.apache.org/licenses/LICENSE-2.0
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 edu.internet2.middleware.grouper;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.excludeDescription;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.excludeDisplayExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.excludeExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.includeDescription;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.includeDisplayExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.includeExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.overallDescription;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordAndIncludesDescription;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordAndIncludesDisplayExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordAndIncludesExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordDescription;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordDisplayExtensionSuffix;
import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordExtensionSuffix;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.hibernate.CallbackException;
import org.hibernate.Session;
import org.hibernate.classic.Lifecycle;
import org.hibernate.type.StringType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import edu.internet2.middleware.grouper.annotations.GrouperIgnoreClone;
import edu.internet2.middleware.grouper.annotations.GrouperIgnoreDbVersion;
import edu.internet2.middleware.grouper.annotations.GrouperIgnoreFieldConstant;
import edu.internet2.middleware.grouper.app.loader.GrouperLoader;
import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig;
import edu.internet2.middleware.grouper.attr.AttributeDef;
import edu.internet2.middleware.grouper.attr.AttributeDefName;
import edu.internet2.middleware.grouper.attr.AttributeDefType;
import edu.internet2.middleware.grouper.attr.assign.AttributeAssign;
import edu.internet2.middleware.grouper.attr.assign.AttributeAssignEffMshipDelegate;
import edu.internet2.middleware.grouper.attr.assign.AttributeAssignGroupDelegate;
import edu.internet2.middleware.grouper.attr.assign.AttributeAssignMembershipDelegate;
import edu.internet2.middleware.grouper.attr.assign.AttributeAssignable;
import edu.internet2.middleware.grouper.attr.finder.AttributeAssignFinder;
import edu.internet2.middleware.grouper.attr.value.AttributeAssignValue;
import edu.internet2.middleware.grouper.attr.value.AttributeAssignValueResult;
import edu.internet2.middleware.grouper.attr.value.AttributeValueDelegate;
import edu.internet2.middleware.grouper.audit.AuditEntry;
import edu.internet2.middleware.grouper.audit.AuditTypeBuiltin;
import edu.internet2.middleware.grouper.cfg.GrouperConfig;
import edu.internet2.middleware.grouper.changeLog.ChangeLogEntry;
import edu.internet2.middleware.grouper.changeLog.ChangeLogLabels;
import edu.internet2.middleware.grouper.changeLog.ChangeLogTypeBuiltin;
import edu.internet2.middleware.grouper.ddl.GrouperDdlUtils;
import edu.internet2.middleware.grouper.entity.Entity;
import edu.internet2.middleware.grouper.entity.EntityUtils;
import edu.internet2.middleware.grouper.exception.AttributeDefNotFoundException;
import edu.internet2.middleware.grouper.exception.AttributeNotFoundException;
import edu.internet2.middleware.grouper.exception.CompositeNotFoundException;
import edu.internet2.middleware.grouper.exception.GrantPrivilegeAlreadyExistsException;
import edu.internet2.middleware.grouper.exception.GrantPrivilegeException;
import edu.internet2.middleware.grouper.exception.GroupAddException;
import edu.internet2.middleware.grouper.exception.GroupDeleteException;
import edu.internet2.middleware.grouper.exception.GroupModifyAlreadyExistsException;
import edu.internet2.middleware.grouper.exception.GroupModifyException;
import edu.internet2.middleware.grouper.exception.GroupNotFoundException;
import edu.internet2.middleware.grouper.exception.GrouperException;
import edu.internet2.middleware.grouper.exception.GrouperSessionException;
import edu.internet2.middleware.grouper.exception.GrouperValidationException;
import edu.internet2.middleware.grouper.exception.InsufficientPrivilegeException;
import edu.internet2.middleware.grouper.exception.MemberAddAlreadyExistsException;
import edu.internet2.middleware.grouper.exception.MemberAddException;
import edu.internet2.middleware.grouper.exception.MemberDeleteAlreadyDeletedException;
import edu.internet2.middleware.grouper.exception.MemberDeleteException;
import edu.internet2.middleware.grouper.exception.MemberNotFoundException;
import edu.internet2.middleware.grouper.exception.MembershipAlreadyExistsException;
import edu.internet2.middleware.grouper.exception.MembershipNotFoundException;
import edu.internet2.middleware.grouper.exception.RevokePrivilegeAlreadyRevokedException;
import edu.internet2.middleware.grouper.exception.RevokePrivilegeException;
import edu.internet2.middleware.grouper.exception.SchemaException;
import edu.internet2.middleware.grouper.exception.StemAddException;
import edu.internet2.middleware.grouper.exception.StemNotFoundException;
import edu.internet2.middleware.grouper.exception.UnableToPerformAlreadyExistsException;
import edu.internet2.middleware.grouper.exception.UnableToPerformException;
import edu.internet2.middleware.grouper.group.TypeOfGroup;
import edu.internet2.middleware.grouper.hibernate.AuditControl;
import edu.internet2.middleware.grouper.hibernate.GrouperTransaction;
import edu.internet2.middleware.grouper.hibernate.GrouperTransactionHandler;
import edu.internet2.middleware.grouper.hibernate.GrouperTransactionType;
import edu.internet2.middleware.grouper.hibernate.HibUtils;
import edu.internet2.middleware.grouper.hibernate.HibUtilsMapping;
import edu.internet2.middleware.grouper.hibernate.HibernateHandler;
import edu.internet2.middleware.grouper.hibernate.HibernateHandlerBean;
import edu.internet2.middleware.grouper.hibernate.HibernateSession;
import edu.internet2.middleware.grouper.hooks.GroupHooks;
import edu.internet2.middleware.grouper.hooks.beans.HooksGroupBean;
import edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook;
import edu.internet2.middleware.grouper.hooks.logic.GrouperHookType;
import edu.internet2.middleware.grouper.hooks.logic.GrouperHooksUtils;
import edu.internet2.middleware.grouper.hooks.logic.HookVeto;
import edu.internet2.middleware.grouper.hooks.logic.VetoTypeGrouper;
import edu.internet2.middleware.grouper.instrumentation.InstrumentationDataBuiltinTypes;
import edu.internet2.middleware.grouper.instrumentation.InstrumentationThread;
import edu.internet2.middleware.grouper.internal.dao.GrouperDAOException;
import edu.internet2.middleware.grouper.internal.dao.QueryOptions;
import edu.internet2.middleware.grouper.internal.dao.hib3.Hib3GrouperVersioned;
import edu.internet2.middleware.grouper.internal.util.GrouperUuid;
import edu.internet2.middleware.grouper.internal.util.Quote;
import edu.internet2.middleware.grouper.internal.util.U;
import edu.internet2.middleware.grouper.log.EventLog;
import edu.internet2.middleware.grouper.member.SearchStringEnum;
import edu.internet2.middleware.grouper.member.SortStringEnum;
import edu.internet2.middleware.grouper.membership.MembershipType;
import edu.internet2.middleware.grouper.misc.CompositeType;
import edu.internet2.middleware.grouper.misc.E;
import edu.internet2.middleware.grouper.misc.GrouperDAOFactory;
import edu.internet2.middleware.grouper.misc.GrouperHasContext;
import edu.internet2.middleware.grouper.misc.GrouperObject;
import edu.internet2.middleware.grouper.misc.GrouperSessionHandler;
import edu.internet2.middleware.grouper.misc.GrouperVersion;
import edu.internet2.middleware.grouper.misc.M;
import edu.internet2.middleware.grouper.misc.Owner;
import edu.internet2.middleware.grouper.misc.SaveMode;
import edu.internet2.middleware.grouper.permissions.PermissionRoleDelegate;
import edu.internet2.middleware.grouper.permissions.role.Role;
import edu.internet2.middleware.grouper.permissions.role.RoleHierarchyType;
import edu.internet2.middleware.grouper.permissions.role.RoleInheritanceDelegate;
import edu.internet2.middleware.grouper.permissions.role.RoleSet;
import edu.internet2.middleware.grouper.privs.AccessPrivilege;
import edu.internet2.middleware.grouper.privs.AccessResolver;
import edu.internet2.middleware.grouper.privs.Privilege;
import edu.internet2.middleware.grouper.privs.PrivilegeHelper;
import edu.internet2.middleware.grouper.rules.RuleCheckType;
import edu.internet2.middleware.grouper.rules.RuleDefinition;
import edu.internet2.middleware.grouper.rules.RuleEngine;
import edu.internet2.middleware.grouper.rules.RuleThenEnum;
import edu.internet2.middleware.grouper.rules.RuleUtils;
import edu.internet2.middleware.grouper.rules.beans.RulesMembershipBean;
import edu.internet2.middleware.grouper.rules.beans.RulesPrivilegeBean;
import edu.internet2.middleware.grouper.subj.GrouperSubject;
import edu.internet2.middleware.grouper.subj.LazySubject;
import edu.internet2.middleware.grouper.subj.SubjectHelper;
import edu.internet2.middleware.grouper.tableIndex.TableIndex;
import edu.internet2.middleware.grouper.tableIndex.TableIndexType;
import edu.internet2.middleware.grouper.util.GrouperUtil;
import edu.internet2.middleware.grouper.util.PerformanceLogger;
import edu.internet2.middleware.grouper.validator.AddAlternateGroupNameValidator;
import edu.internet2.middleware.grouper.validator.AddCompositeMemberValidator;
import edu.internet2.middleware.grouper.validator.CanOptinValidator;
import edu.internet2.middleware.grouper.validator.CanOptoutValidator;
import edu.internet2.middleware.grouper.validator.CompositeValidator;
import edu.internet2.middleware.grouper.validator.FieldTypeValidator;
import edu.internet2.middleware.grouper.validator.GrouperValidator;
import edu.internet2.middleware.grouper.validator.NamingValidator;
import edu.internet2.middleware.grouper.validator.NotNullOrEmptyValidator;
import edu.internet2.middleware.grouper.validator.NotNullValidator;
import edu.internet2.middleware.grouper.xml.export.XmlExportGroup;
import edu.internet2.middleware.grouper.xml.export.XmlImportable;
import edu.internet2.middleware.subject.Source;
import edu.internet2.middleware.subject.SourceUnavailableException;
import edu.internet2.middleware.subject.Subject;
import edu.internet2.middleware.subject.SubjectNotFoundException;
import edu.internet2.middleware.subject.SubjectNotUniqueException;
/**
* A group within the Groups Registry.
*
* @author blair christensen.
* @version $Id: Group.java,v 1.269 2009-12-15 06:47:06 mchyzer Exp $
*/
@SuppressWarnings("serial")
public class Group extends GrouperAPI implements Role, GrouperHasContext, Owner,
Hib3GrouperVersioned, Comparable, XmlImportable, AttributeAssignable, Entity, GrouperObject {
/**
*
*/
public static final String VALIDATION_GROUP_DESCRIPTION_TOO_LONG_KEY = "groupDescriptionTooLong";
/**
*
*/
public static final String VALIDATION_GROUP_DISPLAY_EXTENSION_TOO_LONG_KEY = "groupDisplayExtensionTooLong";
/**
*
*/
public static final String VALIDATION_GROUP_EXTENSION_TOO_LONG_KEY = "groupExtensionTooLong";
/**
*
*/
public static final String VALIDATION_GROUP_DISPLAY_NAME_TOO_LONG_KEY = "groupDisplayNameTooLong";
/**
*
*/
public static final String VALIDATION_GROUP_NAME_TOO_LONG_KEY = "groupNameTooLong";
/** name of the groups table in the db */
public static final String TABLE_GROUPER_GROUPS = "grouper_groups";
/** uuid col in db (not used anymore) */
public static final String COLUMN_UUID = "uuid";
/** id col in db */
public static final String COLUMN_ID = "id";
/** col in db */
public static final String COLUMN_PARENT_STEM = "parent_stem";
/** col in db */
public static final String COLUMN_CREATOR_ID = "creator_id";
/** col in db */
public static final String COLUMN_CREATE_TIME = "create_time";
/** col in db */
public static final String COLUMN_MODIFIER_ID = "modifier_id";
/** col in db */
public static final String COLUMN_MODIFY_TIME = "modify_time";
/** col in db */
public static final String COLUMN_NAME = "name";
/** col in db */
public static final String COLUMN_DISPLAY_NAME = "display_name";
/** col in db */
public static final String COLUMN_EXTENSION = "extension";
/** col in db */
public static final String COLUMN_DISPLAY_EXTENSION = "display_extension";
/** col in db */
public static final String COLUMN_DESCRIPTION = "description";
/** old id col for id conversion */
public static final String COLUMN_OLD_ID = "old_id";
/** old uuid id col for id conversion */
public static final String COLUMN_OLD_UUID = "old_uuid";
/** timestamp of the last membership change for this group */
public static final String COLUMN_LAST_MEMBERSHIP_CHANGE = "last_membership_change";
/** timestamp of the last immediate membership change for this group */
public static final String COLUMN_LAST_IMMEDIATE_MEMBERSHIP_CHANGE = "last_imm_membership_change";
/** an alternate name for this group */
public static final String COLUMN_ALTERNATE_NAME = "alternate_name";
/** if this is a group or role */
public static final String COLUMN_TYPE_OF_GROUP = "type_of_group";
/** unique number for this group */
public static final String COLUMN_ID_INDEX = "id_index";
/** epoch time of when to disable membership */
public static final String COLUMN_DISABLED_TIMESTAMP = "disabled_timestamp";
/** epoch time of when to enable membership */
public static final String COLUMN_ENABLED_TIMESTAMP = "enabled_timestamp";
/** whether the membership is enabled or disabled: T|F */
public static final String COLUMN_ENABLED = "enabled";
/**
* if this is a composite group, get the composite object for this group
* @return the composite group
* @throws CompositeNotFoundException if composite not found
* @deprecated use the overload with boolean instead
*/
@Deprecated
public Composite getComposite() throws CompositeNotFoundException {
return this.getComposite(true);
}
/**
* if this is a composite group, get the composite object for this group
* @param throwExceptionIfNotFound
* @return the composite group or null if none
* @throws CompositeNotFoundException if not found and throwExceptionIfNotFound is true
*/
public Composite getComposite(boolean throwExceptionIfNotFound) {
try {
return CompositeFinder.findAsOwner(this, true);
} catch (CompositeNotFoundException cnfe) {
if (throwExceptionIfNotFound) {
throw cnfe;
}
return null;
}
}
/**
*
* create or update a group. Note this will not rename a group at this time (might in future)
*
* This is a static method since setters to Group objects persist to the DB
*
* Steps:
*
* 1. Find the group by groupNameToEdit
* 2. Internally set all the fields of the stem (no need to reset if already the same)
* 3. Store the group (insert or update) if needed
* 4. Return the group object
*
* This runs in a tx so that if part of it fails the whole thing fails, and potentially the outer
* transaction too
*
* @param GROUPER_SESSION to act as
* @param groupNameToEdit is the name of the group to edit (or null if insert)
* @param description new description for group
* @param displayExtension display friendly name for this group only
* (parent stems are not specified)
* @param name this is required, and is the full name of the group
* including the names of parent stems. e.g. stem1:stem2:stem3
* the parent stem must exist unless createParentStemsIfNotExist.
* Can rename a stem extension, but not the parent stem name (move)
* @param uuid of the group. If a group exists with this uuid, then it will
* be updated, if not, then it will be created if createIfNotExist is true
* @param saveMode to constrain if insert only or update only, if null defaults to INSERT_OR_UPDATE
* @param createParentStemsIfNotExist true if the stems should be created if they dont exist, false
* for StemNotFoundException if not exist. Note, the display extension on created stems
* will equal the extension
* @return the stem that was updated or created
* @throws StemNotFoundException
* @throws InsufficientPrivilegeException
* @throws StemAddException
* @throws GroupModifyException
* @throws GroupNotFoundException
* @throws GroupAddException
*/
public static Group saveGroup(final GrouperSession GROUPER_SESSION, final String groupNameToEdit,
final String uuid, final String name, final String displayExtension, final String description,
SaveMode saveMode, final boolean createParentStemsIfNotExist)
throws StemNotFoundException, InsufficientPrivilegeException, StemAddException,
GroupModifyException, GroupNotFoundException, GroupAddException {
GroupSave groupSave = new GroupSave(GROUPER_SESSION);
groupSave.assignGroupNameToEdit(groupNameToEdit).assignUuid(uuid);
groupSave.assignName(name).assignDisplayExtension(displayExtension);
groupSave.assignDescription(description).assignSaveMode(saveMode);
groupSave.assignCreateParentStemsIfNotExist(createParentStemsIfNotExist);
Group group = groupSave.save();
return group;
}
/** */
private static final EventLog EVENT_LOG = new EventLog();
/** */
private static final String KEY_CREATOR = "creator"; // for state caching
/** */
private static final String KEY_MODIFIER = "modifier"; // for state caching
/** */
private static final String KEY_SUBJECT = "subject"; // for state caching
/** */
@GrouperIgnoreDbVersion
@GrouperIgnoreFieldConstant
@GrouperIgnoreClone
private Member cachedMember = null;
/** */
@GrouperIgnoreDbVersion
@GrouperIgnoreFieldConstant
@GrouperIgnoreClone
private HashMap subjectCache = new HashMap();
// TODO 20070531 review lazy-loading to improve consistency + performance
/** */
@GrouperIgnoreDbVersion
@GrouperIgnoreFieldConstant
@GrouperIgnoreClone
// caching legacy attributes with the group object like they were cached < 2.2
// the key is the legacy attribute name.
private Map attributes;
/** */
private long createTime = 0; // default to the epoch
/** */
private String creatorUUID;
/** */
private String modifierUUID;
/** */
private long modifyTime = 0; // default to the epoch
/** */
private String parentUuid;
/** default to group type, as opposed to role */
private TypeOfGroup typeOfGroup = TypeOfGroup.group;
/** caching legacy group types with the group object like they were cached < 2.2
* keys are the legacy group type names (i.e. without prefix or path) */
@GrouperIgnoreDbVersion
@GrouperIgnoreFieldConstant
@GrouperIgnoreClone
private Map types;
/** cache type assignments as well for the same reason */
private Map typeAssignments;
/** */
private String uuid;
/** name of group, e.g. school:community:students */
private String name;
/** alternate name of group */
private String alternateNameDb;
/** displayName of group, e.g. My School:Community Groups:All Students */
private String displayName;
/** extension of group, e.g. students */
private String extension;
/** id of the group as a unique integer */
private Long idIndex;
/** displayExtension of group, e.g. All Students */
private String displayExtension;
/** description of group, friendly description, e.g. in sentence form, about what the group is about */
private String description;
/** context id of the transaction */
private String contextId;
/**
* If the group is enabled.
*/
private boolean enabled = true;
/**
* Time to enable this group.
*/
private Long enabledTimeDb;
/**
* Time to disable this group.
*/
private Long disabledTimeDb;
/**
* context id of the transaction
* @return context id
*/
public String getContextId() {
return this.contextId;
}
/**
* context id of the transaction
* @param contextId1
*/
public void setContextId(String contextId1) {
this.contextId = contextId1;
}
//***** START GENERATED WITH GenerateFieldConstants.java *****//
/** constant for field name for: alternateNameDb */
public static final String FIELD_ALTERNATE_NAME_DB = "alternateNameDb";
/** constant for field name for: createTime */
public static final String FIELD_CREATE_TIME = "createTime";
/** constant for field name for: creatorUUID */
public static final String FIELD_CREATOR_UUID = "creatorUUID";
/** constant for field name for: dbVersion */
public static final String FIELD_DB_VERSION = "dbVersion";
/** constant for field name for: description */
public static final String FIELD_DESCRIPTION = "description";
/** constant for field name for: displayExtension */
public static final String FIELD_DISPLAY_EXTENSION = "displayExtension";
/** constant for field name for: displayName */
public static final String FIELD_DISPLAY_NAME = "displayName";
/** constant for field name for: extension */
public static final String FIELD_EXTENSION = "extension";
/** constant for field name for: idIndex */
public static final String FIELD_ID_INDEX = "idIndex";
/** constant for field name for: lastMembershipChangeDb */
public static final String FIELD_LAST_MEMBERSHIP_CHANGE_DB = "lastMembershipChangeDb";
/** constant for field name for: lastImmediateMembershipChangeDb */
public static final String FIELD_LAST_IMMEDIATE_MEMBERSHIP_CHANGE_DB = "lastImmediateMembershipChangeDb";
/** constant for field name for: modifierUUID */
public static final String FIELD_MODIFIER_UUID = "modifierUUID";
/** constant for field name for: modifyTime */
public static final String FIELD_MODIFY_TIME = "modifyTime";
/** constant for field name for: name */
public static final String FIELD_NAME = "name";
/** constant for field name for: parentUuid */
public static final String FIELD_PARENT_UUID = "parentUuid";
/** constant for field name for: typeOfGroup */
public static final String FIELD_TYPE_OF_GROUP = "typeOfGroup";
/** constant for field name for: uuid */
public static final String FIELD_UUID = "uuid";
/** constant for field name for: disabledTimeDb */
public static final String FIELD_DISABLED_TIME_DB = "disabledTimeDb";
/** constant for field name for: enabled */
public static final String FIELD_ENABLED = "enabled";
/** constant for field name for: enabledTimeDb */
public static final String FIELD_ENABLED_TIME_DB = "enabledTimeDb";
/**
* fields which are included in db version
*/
private static final Set DB_VERSION_FIELDS = GrouperUtil.toSet(
FIELD_CREATE_TIME, FIELD_CREATOR_UUID, FIELD_DESCRIPTION,
FIELD_DISPLAY_EXTENSION, FIELD_DISPLAY_NAME, FIELD_EXTENSION, FIELD_MODIFIER_UUID,
FIELD_MODIFY_TIME, FIELD_NAME, FIELD_PARENT_UUID, FIELD_TYPE_OF_GROUP, FIELD_UUID,
FIELD_ID_INDEX, FIELD_DISABLED_TIME_DB, FIELD_ENABLED, FIELD_ENABLED_TIME_DB,
FIELD_ALTERNATE_NAME_DB, FIELD_LAST_MEMBERSHIP_CHANGE_DB, FIELD_LAST_IMMEDIATE_MEMBERSHIP_CHANGE_DB);
/**
* fields which are included in clone method
*/
private static final Set CLONE_FIELDS = GrouperUtil.toSet(
FIELD_CREATE_TIME, FIELD_CREATOR_UUID, FIELD_DB_VERSION,
FIELD_DESCRIPTION, FIELD_DISPLAY_EXTENSION, FIELD_DISPLAY_NAME, FIELD_EXTENSION,
FIELD_HIBERNATE_VERSION_NUMBER, FIELD_ID_INDEX, FIELD_MODIFIER_UUID, FIELD_MODIFY_TIME, FIELD_NAME,
FIELD_PARENT_UUID, FIELD_TYPE_OF_GROUP, FIELD_UUID, FIELD_LAST_MEMBERSHIP_CHANGE_DB,
FIELD_ALTERNATE_NAME_DB, FIELD_LAST_IMMEDIATE_MEMBERSHIP_CHANGE_DB,
FIELD_DISABLED_TIME_DB, FIELD_ENABLED, FIELD_ENABLED_TIME_DB);
//***** END GENERATED WITH GenerateFieldConstants.java *****//
/**
* Should this group be enabled based on the enabled and disabled dates?
* @return boolean
*/
public boolean internal_isEnabledUsingTimestamps() {
long now = System.currentTimeMillis();
if (this.enabledTimeDb != null && this.enabledTimeDb > now) {
return false;
}
if (this.disabledTimeDb != null && this.disabledTimeDb < now) {
return false;
}
return true;
}
/**
* Is this group enabled?
* @return boolean
*/
public boolean isEnabled() {
return this.enabled;
}
/**
* Whether to enable or disable this group.
* @param enabled
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* Whether or not this group is enabled.
* @return the enabled
*/
public String getEnabledDb() {
if (this.enabled) {
return "T";
}
return "F";
}
/**
* Whether to enable or disable this group.
* @param enabled
*/
public void setEnabledDb(String enabled) {
this.enabled = GrouperUtil.booleanValue(enabled);
}
/**
* Time when this group is enabled if the value is in the future.
* @return Long
*/
public Long getEnabledTimeDb() {
return this.enabledTimeDb;
}
/**
* Time when this group is enabled if the value is in the future.
* @return Timestamp
*/
public Timestamp getEnabledTime() {
if (this.enabledTimeDb == null) {
return null;
}
return new Timestamp(this.enabledTimeDb);
}
/**
* Set the time when this group should be enabled.
* @param enabledTimeDb
*/
public void setEnabledTimeDb(Long enabledTimeDb) {
this.enabledTimeDb = enabledTimeDb;
}
/**
* Set the time when this group should be enabled.
* @param enabledTimeDb
*/
public void setEnabledTime(Timestamp enabledTimeDb) {
if (enabledTimeDb == null) {
this.enabledTimeDb = null;
} else {
this.enabledTimeDb = enabledTimeDb.getTime();
}
setEnabled(internal_isEnabledUsingTimestamps());
}
/**
* Time when this group is disabled if the value is in the future.
* @return Long
*/
public Long getDisabledTimeDb() {
return this.disabledTimeDb;
}
/**
* Time when this group is disabled if the value is in the future.
* @return Timestamp
*/
public Timestamp getDisabledTime() {
if (this.disabledTimeDb == null) {
return null;
}
return new Timestamp(this.disabledTimeDb);
}
/**
* Set the time to disable this group.
* @param disabledTimeDb
*/
public void setDisabledTimeDb(Long disabledTimeDb) {
this.disabledTimeDb = disabledTimeDb;
}
/**
* Set the time to disable this group.
* @param disabledTimeDb
*/
public void setDisabledTime(Timestamp disabledTimeDb) {
if (disabledTimeDb == null) {
this.disabledTimeDb = null;
} else {
this.disabledTimeDb = disabledTimeDb.getTime();
}
setEnabled(this.internal_isEnabledUsingTimestamps());
}
/** */
@GrouperIgnoreClone @GrouperIgnoreDbVersion @GrouperIgnoreFieldConstant @JsonIgnore
private AttributeAssignGroupDelegate attributeAssignGroupDelegate;
/**
*
* @return the delegate
*/
public AttributeAssignGroupDelegate getAttributeDelegate() {
if (this.attributeAssignGroupDelegate == null) {
this.attributeAssignGroupDelegate = new AttributeAssignGroupDelegate(this);
}
return this.attributeAssignGroupDelegate;
}
/** */
@GrouperIgnoreClone @GrouperIgnoreDbVersion @GrouperIgnoreFieldConstant @JsonIgnore
private AttributeValueDelegate attributeValueDelegate;
/**
* this delegate works on attributes and values at the same time
* @return the delegate
*/
public AttributeValueDelegate getAttributeValueDelegate() {
if (this.attributeValueDelegate == null) {
this.attributeValueDelegate = new AttributeValueDelegate(this.getAttributeDelegate());
}
return this.attributeValueDelegate;
}
/**
* delegate for effective memberships
* @param member
* @return the delegate
*/
public AttributeAssignEffMshipDelegate getAttributeDelegateEffMship(Member member) {
return new AttributeAssignEffMshipDelegate(this, member);
}
/**
* this delegate works on attributes and values at the same time
* @param member
* @return the delegate
*/
public AttributeValueDelegate getAttributeValueDelegateEffMship(Member member) {
return new AttributeValueDelegate(this.getAttributeDelegateEffMship(member));
}
/**
* delegate for effective memberships
* @param member
* @return the delegate
*/
public AttributeAssignMembershipDelegate getAttributeDelegateMembership(Member member) {
return getAttributeDelegateMembership(member, Group.getDefaultList());
}
/**
* delegate for effective memberships
* @param member
* @param field
* @return the delegate
*/
public AttributeAssignMembershipDelegate getAttributeDelegateMembership(Member member, Field field) {
Membership membership = MembershipFinder.findImmediateMembership(GrouperSession.staticGrouperSession(),
this, member.getSubject(), field, false);
if (membership == null) {
throw new RuntimeException("Cannot get the immediate membership attribute delegate if not an immediate member: "
+ this + ", " + GrouperUtil.subjectToString(member.getSubject()) + ", " + field);
}
return new AttributeAssignMembershipDelegate(membership);
}
/**
* this delegate works on attributes and values at the same time
* @param member
* @param field
* @return the delegate
*/
public AttributeValueDelegate getAttributeValueDelegateMembership(Member member, Field field) {
return new AttributeValueDelegate(this.getAttributeDelegateMembership(member, field));
}
/**
* this delegate works on attributes and values at the same time
* @param member
* @return the delegate
*/
public AttributeValueDelegate getAttributeValueDelegateMembership(Member member) {
return new AttributeValueDelegate(this.getAttributeDelegateMembership(member));
}
/**
* Retrieve default members {@link Field}.
*
* Field members = Group.getDefaultList();
*
* @return The "members" {@link Field}
* @throws GrouperException
*/
public static Field getDefaultList() throws GrouperException {
return FieldFinder.find(GrouperConfig.LIST, true);
}
/** logger */
private static final Log LOG = GrouperUtil.getLog(Group.class);
/**
* Add ore replace a composite membership to this group.
*
* try {
* g.assignCompositeMember(CompositeType.UNION, leftGroup, rightGroup);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add composite membership
* }
*
* @param type Add membership of this {@link CompositeType}.
* @param left {@link Group} that is left factor of of composite membership.
* @param right {@link Group} that is right factor of composite membership.
* @throws InsufficientPrivilegeException
* @throws MemberAddException
* @throws MemberDeleteException
* @since 1.0
*/
public void assignCompositeMember(final CompositeType type, final Group left, final Group right)
throws InsufficientPrivilegeException, MemberAddException, MemberDeleteException {
final String errorMessageSuffix = ", group name: " + this.name + ", compositeType: " + type
+ ", left group name: " + (left == null ? "null" : left.getName())
+ ", right group name: " + (right == null ? "null" : right.getName());
Composite composite = null;
try {
composite = this.getComposite();
} catch (CompositeNotFoundException cnfe) {
}
if (composite != null) {
//if not equal, replace, otherwise leave alone
if (!composite.getTypeDb().equals(type.getName())
|| !composite.getLeftFactorUuid().equals(left.getUuid())
|| !composite.getRightFactorUuid().equals(right.getUuid())) {
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting and adding composite member for group: " + this.getExtension() + ": "
+ type.getName() + ": " + left.getExtension() + " - " + right.getExtension());
}
final StringBuilder differences = new StringBuilder();
if (!composite.getTypeDb().equals(type.getName())) {
differences.append("type from: " + composite.getTypeDb() + " to: " + type.getName());
}
if (!composite.getLeftFactorUuid().equals(left.getUuid())) {
try {
differences.append("left group from: " + composite.getLeftGroup().getName() + ", to: " + left.getName());
} catch (GroupNotFoundException gnfe) {
differences.append("left group from: " + composite.getLeftFactorUuid() + ", to: " + left.getName());
}
}
if (!composite.getRightFactorUuid().equals(right.getUuid())) {
try {
differences.append("right group from: " + composite.getRightGroup().getName() + ", to: " + right.getName());
} catch (GroupNotFoundException gnfe) {
differences.append("right group from: " + composite.getRightFactorUuid() + ", to: " + right.getName());
}
}
final Composite COMPOSITE = composite;
HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
try {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
Group.this.deleteCompositeMember();
Group.this.addCompositeMember(type, left, right);
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.GROUP_COMPOSITE_UPDATE, "id",
COMPOSITE.getUuid(), "ownerId", Group.this.getUuid(), "ownerName", Group.this.getName(), "leftFactorId",
left.getUuid(), "leftFactorName", left.getName(), "rightFactorId", right.getUuid(),
"rightFactorName", right.getName(), "type", type.toString());
auditEntry.setDescription("Updated composite: " + Group.this.getName() + ", " + differences.toString());
auditEntry.saveOrUpdate(true);
}
return null;
} catch (MemberAddException mae) {
GrouperUtil.injectInException(mae, errorMessageSuffix);
throw mae;
} catch (RuntimeException re) {
GrouperUtil.injectInException(re, errorMessageSuffix);
throw re;
}
}
});
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Adding composite member for group: " + this.getExtension() + ": "
+ type.getName() + ": " + left.getExtension() + " - " + right.getExtension());
}
this.addCompositeMember(type, left, right);
}
}
/**
* Add a composite membership to this group.
*
* try {
* g.addCompositeMember(CompositeType.UNION, leftGroup, rightGroup);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add composite membership
* }
*
* @param type Add membership of this {@link CompositeType}.
* @param left {@link Group} that is left factor of of composite membership.
* @param right {@link Group} that is right factor of composite membership.
* @return composite
* @throws InsufficientPrivilegeException
* @throws MemberAddException
* @since 1.0
*/
public Composite addCompositeMember(CompositeType type, Group left, Group right)
throws InsufficientPrivilegeException,
MemberAddException {
return internal_addCompositeMember(GrouperSession.staticGrouperSession(), type, left, right, null);
}
/**
* Add a subject to this group as immediate member.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.addMember(subj);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add subject
* }
*
* @param subj Add this {@link Subject}
* @throws InsufficientPrivilegeException
* @throws MemberAddException
*/
public void addMember(Subject subj)
throws InsufficientPrivilegeException,
MemberAddException
{
this.addMember(subj, true);
} // public void addMember(subj)
/**
* Add a subject to this group as immediate member.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.addMember(subj);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add subject
* }
*
* @param subj Add this {@link Subject}
* @param exceptionIfAlreadyMember if false, and subject is already a member,
* then dont throw a MemberAddException if the member is already in the group
* @return false if it already existed, true if it didnt already exist
* @throws InsufficientPrivilegeException
* @throws MemberAddException
*/
public boolean addMember(Subject subj, boolean exceptionIfAlreadyMember)
throws InsufficientPrivilegeException,
MemberAddException
{
try {
Field defaultList = getDefaultList();
return this.addMember(subj, defaultList, exceptionIfAlreadyMember);
}
catch (SchemaException eS) {
throw new MemberAddException(eS.getMessage(), eS);
}
} // public void addMember(subj)
/**
* Add a subject to this group as immediate member.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.addMember(subj, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add member
* }
* catch (SchemaException eS) {
* // Invalid Field
* }
*
* @param subj Add this {@link Subject}
* @param f Add subject to this {@link Field}.
* @throws InsufficientPrivilegeException
* @throws MemberAddException
* @throws SchemaException
*/
public void addMember(Subject subj, Field f)
throws InsufficientPrivilegeException,
MemberAddException,
SchemaException
{
this.addMember(subj, f, true);
} // public void addMember(subj, f)
/**
* Add a subject to this group as immediate member.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.addMember(subj, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add member
* }
* catch (SchemaException eS) {
* // Invalid Field
* }
*
* @param subj Add this {@link Subject}
* @param f Add subject to this {@link Field}.
* @param exceptionIfAlreadyMember if false, and subject is already a member,
* then dont throw a MemberAddException if the member is already in the group
* @throws InsufficientPrivilegeException
* @throws MemberAddException
* @throws SchemaException
* @return false if it already existed, true if it didnt already exist
*/
public boolean addMember(final Subject subj, final Field f, final boolean exceptionIfAlreadyMember)
throws InsufficientPrivilegeException,
MemberAddException, SchemaException {
return this.internal_addMember(subj, f, exceptionIfAlreadyMember, null, null, null);
}
/**
* replace the member list with new list. Note this is not done in a tx so it can make as much progress as possible
* though feel free to put a tx outside of the call if you need it
* @param newSubjectList
* @return the number of members changed
*/
public int replaceMembers(Collection newSubjectList) {
return replaceMembers(newSubjectList, Group.getDefaultList());
}
/**
* replace the member list with new list. Note this is not done in a tx so it can make as much progress as possible
* though feel free to put a tx outside of the call if you need it
* @param newSubjectList
* @param field
* @return the number of members changed
*/
public int replaceMembers(Collection newSubjectList, Field field) {
Map infoMap = new HashMap();
infoMap.put("operation", "replaceMembers");
infoMap.put("groupName", this.getName());
try {
Set existingMembers = GrouperUtil.nonNull(this.getImmediateMembers(field));
infoMap.put("existingMemberListSize", GrouperUtil.length(existingMembers));
infoMap.put("newMemberListSize", GrouperUtil.length(newSubjectList));
Set existingSubjects = existingMembers.stream().map(Member::getSubject).collect(Collectors.toSet());
Set subjectsToAdd = GrouperUtil.nonNull(newSubjectList).stream().collect(Collectors.toSet());
subjectsToAdd.removeAll(existingSubjects);
Set subjectsToRemove = new HashSet<>(existingSubjects);
subjectsToRemove.removeAll(GrouperUtil.nonNull(newSubjectList));
int changedRecords = 0;
int addedMemberCount = 0;
int deletedMemberCount = 0;
for (Subject newSubject: subjectsToAdd) {
this.addMember(newSubject, field, true);
if (LOG.isDebugEnabled()) {
LOG.debug("Replace members on " + this.getName() + ": Subject "
+ newSubject.getSourceId() + " - " + newSubject.getId() + " is added");
}
changedRecords++;
addedMemberCount++;
}
infoMap.put("addedMemberCount", addedMemberCount);
for (Subject removeMember: subjectsToRemove) {
this.deleteMember(removeMember, field, true);
if (LOG.isDebugEnabled()) {
LOG.debug("Replace members on " + this.getName() + ": Subject "
+ removeMember.getSourceId() + " - " + removeMember.getId() + " is removed");
}
changedRecords++;
deletedMemberCount++;
}
infoMap.put("deletedMemberCount", deletedMemberCount);
infoMap.put("changedRecords", changedRecords);
if (LOG.isInfoEnabled()) {
LOG.info(GrouperUtil.mapToString(infoMap));
}
return changedRecords;
} catch (RuntimeException re) {
LOG.error(GrouperUtil.mapToString(infoMap));
throw re;
}
}
/**
* add a member to group, take into account if any default privs should be changed
* @param subject to add
* @param defaultPrivs if true, forget about all the other checked params
* @param memberChecked
* @param adminChecked
* @param updateChecked
* @param readChecked
* @param viewChecked
* @param optinChecked
* @param optoutChecked
* @param attrReadChecked
* @param attrUpdateChecked
* @param startDate on membership
* @param endDate on membership
* @param revokeIfUnchecked
* @return if something was changed
* @deprecated use addOrEditMember instead
*/
@Deprecated
public boolean addMember(final Subject subject, final boolean defaultPrivs,
final boolean memberChecked,
final boolean adminChecked,
final boolean updateChecked, final boolean readChecked, final boolean viewChecked,
final boolean optinChecked, final boolean optoutChecked, final boolean attrReadChecked,
final boolean attrUpdateChecked, final Date startDate, final Date endDate, final boolean revokeIfUnchecked) {
return this.addOrEditMember(subject, defaultPrivs, memberChecked, adminChecked, updateChecked,
readChecked, viewChecked, optinChecked, optoutChecked, attrReadChecked, attrUpdateChecked,
startDate, endDate, revokeIfUnchecked);
}
/**
* add a member to group, take into account if any default privs should be changed
* @param subject to add
* @param defaultPrivs if true, forget about all the other checked params
* @param memberChecked
* @param adminChecked
* @param updateChecked
* @param readChecked
* @param viewChecked
* @param optinChecked
* @param optoutChecked
* @param attrReadChecked
* @param attrUpdateChecked
* @param startDate on membership
* @param endDate on membership
* @param revokeIfUnchecked
* @return if something was changed
*/
public boolean addOrEditMember(final Subject subject, final boolean defaultPrivs,
final boolean memberChecked,
final boolean adminChecked,
final boolean updateChecked, final boolean readChecked, final boolean viewChecked,
final boolean optinChecked, final boolean optoutChecked, final boolean attrReadChecked,
final boolean attrUpdateChecked, final Date startDate, final Date endDate, final boolean revokeIfUnchecked) {
return (Boolean)GrouperTransaction.callbackGrouperTransaction(GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, new GrouperTransactionHandler() {
@Override
public Object callback(GrouperTransaction grouperTransaction)
throws GrouperDAOException {
boolean hadChange = Group.this.addOrEditMember(subject, defaultPrivs, memberChecked, startDate, endDate, revokeIfUnchecked);
if (!defaultPrivs) {
//see if add or remove
if (adminChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.ADMIN, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.ADMIN, false);
}
}
//see if add or remove
if (updateChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.UPDATE, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.UPDATE, false);
}
}
//see if add or remove
if (readChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.READ, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.READ, false);
}
}
//see if add or remove
if (viewChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.VIEW, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.VIEW, false);
}
}
//see if add or remove
if (optinChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.OPTIN, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.OPTIN, false);
}
}
//see if add or remove
if (optoutChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.OPTOUT, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.OPTOUT, false);
}
}
//see if add or remove
if (attrReadChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.GROUP_ATTR_READ, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.GROUP_ATTR_READ, false);
}
}
//see if add or remove
if (attrUpdateChecked) {
hadChange = hadChange | Group.this.grantPriv(subject, AccessPrivilege.GROUP_ATTR_UPDATE, false);
} else {
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.revokePriv(subject, AccessPrivilege.GROUP_ATTR_UPDATE, false);
}
}
}
return hadChange;
}
});
}
/**
* add a member to group, take into account if any default privs should be changed
* @param subject to add
* @param defaultPrivs if true, forget about all the other checked params
* @param memberChecked
* @param startDate on membership
* @param endDate on membership
* @param revokeIfUnchecked
* @return if something was changed
* @deprecated use addOrEditMember instead
*/
@Deprecated
public boolean addMember(final Subject subject, final boolean defaultPrivs,
final boolean memberChecked, final Date startDate, final Date endDate, final boolean revokeIfUnchecked) {
return this.addOrEditMember(subject, defaultPrivs, memberChecked, startDate, endDate, revokeIfUnchecked);
}
/**
* add a member to group, take into account if any default privs should be changed
* @param subject to add
* @param defaultPrivs if true, forget about all the other checked params
* @param memberChecked
* @param startDate on membership
* @param endDate on membership
* @param revokeIfUnchecked
* @return if something was changed
*/
public boolean addOrEditMember(final Subject subject, final boolean defaultPrivs,
final boolean memberChecked, final Date startDate, final Date endDate, final boolean revokeIfUnchecked) {
return (Boolean)GrouperTransaction.callbackGrouperTransaction(GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, new GrouperTransactionHandler() {
@Override
public Object callback(GrouperTransaction grouperTransaction)
throws GrouperDAOException {
boolean addedMember = defaultPrivs || memberChecked || startDate != null || endDate != null;
boolean hadChange = false;
if (addedMember) {
Field field = Group.getDefaultList();
Member member = MemberFinder.findBySubject(GrouperSession.staticGrouperSession(), subject, true);
//see if member
Membership membership =
GrouperDAOFactory.getFactory().getMembership().findByGroupOwnerAndMemberAndFieldAndType(
Group.this.getUuid(), member.getUuid(), field, MembershipType.IMMEDIATE.getTypeString(), false, false);
if (membership != null) {
if ( !Group.this.canHavePrivilege(GrouperSession.staticGrouperSession().getSubject(), field.getWritePrivilege(), false)) {
//if the subject operated on is the subject
if (SubjectHelper.eq(subject, GrouperSession.staticGrouperSession().getSubject())) {
//if cant optin, then invalid
GrouperValidator v = CanOptinValidator.validate(Group.this, subject, field);
if (v.isInvalid()) {
throw new InsufficientPrivilegeException();
}
} else {
throw new InsufficientPrivilegeException();
}
}
//we are already a member, lets see if the dates match up
boolean hasChange = false;
if (!GrouperUtil.equals(startDate, membership.getEnabledTime())) {
hasChange = true;
membership.setEnabledTime(startDate == null ? null : new Timestamp(startDate.getTime()));
}
if (!GrouperUtil.equals(endDate, membership.getDisabledTime())) {
hasChange = true;
membership.setDisabledTime(endDate == null ? null : new Timestamp(endDate.getTime()));
}
//if a date didnt match up, then save the membership
if (hasChange) {
HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
GrouperDAOFactory.getFactory().getMembership().update(membership);
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd h:mm a");
String enabledTimeString = membership.getEnabledTime() == null ? null : sdf.format(membership.getEnabledTime());
String disabledTimeString = membership.getDisabledTime() == null ? null : sdf.format(membership.getDisabledTime());
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.MEMBERSHIP_GROUP_UPDATE, "id",
membership.getUuid(), "fieldId", field.getUuid(),
"fieldName", field.getName(), "memberId", membership.getMemberUuid(),
"membershipType", membership.getType(),
"groupId", Group.this.getUuid(), "groupName", Group.this.getName());
auditEntry.setDescription("Updated membership: group: " + Group.this.getName()
+ ", subject: " + subject.getSource().getId() + "." + subject.getId() + ", field: "
+ field.getName()
+ ", enabledTime: " + enabledTimeString
+ ", disabledTime: " + disabledTimeString);
auditEntry.saveOrUpdate(true);
}
return null;
}
});
}
return hasChange;
}
addedMember = Group.this.internal_addMember(subject, field, false, null, GrouperUtil.toTimestamp(startDate),
GrouperUtil.toTimestamp(endDate));
hadChange = hadChange || addedMember;
} else {
//if they are doing custom privs, maybe they want member removed???
if (revokeIfUnchecked) {
hadChange = hadChange | Group.this.deleteMember(subject, false);
}
}
return hadChange;
}
});
}
/**
* Add a subject to this group as immediate member.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.addMember(subj, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add member
* }
* catch (SchemaException eS) {
* // Invalid Field
* }
*
* @param subj Add this {@link Subject}
* @param f Add subject to this {@link Field}.
* @param exceptionIfAlreadyMember if false, and subject is already a member,
* then dont throw a MemberAddException if the member is already in the group
* @param uuid is uuid or null for generated
* @param startDate
* @param endDate
* @throws InsufficientPrivilegeException
* @throws MemberAddException
* @throws SchemaException
* @return false if it already existed, true if it didnt already exist
*/
public boolean internal_addMember(final Subject subj, final Field f,
final boolean exceptionIfAlreadyMember, final String uuid, final Timestamp startDate, final Timestamp endDate)
throws InsufficientPrivilegeException,
MemberAddException, SchemaException {
return this.internal_addMember(subj, f, exceptionIfAlreadyMember, uuid, startDate, endDate, true);
}
/**
* Add a subject to this group as immediate member.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.addMember(subj, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to add members
* }
* catch (MemberAddException eMA) {
* // Unable to add member
* }
* catch (SchemaException eS) {
* // Invalid Field
* }
*
* @param subj Add this {@link Subject}
* @param f Add subject to this {@link Field}.
* @param exceptionIfAlreadyMember if false, and subject is already a member,
* then dont throw a MemberAddException if the member is already in the group
* @param uuid is uuid or null for generated
* @param startDate
* @param endDate
* @throws InsufficientPrivilegeException
* @throws MemberAddException
* @throws SchemaException
* @return false if it already existed, true if it didnt already exist
*/
public boolean internal_addMember(final Subject subj, final Field f,
final boolean exceptionIfAlreadyMember, final String uuid, final Timestamp startDate, final Timestamp endDate, final boolean checkSecurity)
throws InsufficientPrivilegeException,
MemberAddException, SchemaException {
final StopWatch sw = new StopWatch();
sw.start();
final String errorMessageSuffix = ", group name: " + this.name
+ ", subject: " + GrouperUtil.subjectToString(subj) + ", field: " + (f == null ? null : f.getName());
// do this outside of transaction so that if gets vetoed, the member is there for other things
MemberFinder.findBySubject(GrouperSession.staticGrouperSession(), subj, true);
return (Boolean)HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
try {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
// (12/2021) This constraint was added in 2007 without comment. Seems ok to remove it
//if ( !FieldType.LIST.equals( f.getType() ) ) {
// throw new SchemaException( E.FIELD_INVALID_TYPE + f.getType() );
//}
if (checkSecurity && !Group.this.canWriteField(f) ) {
GrouperValidator v = CanOptinValidator.validate(Group.this, subj, f);
if (v.isInvalid()) {
throw new InsufficientPrivilegeException();
}
}
//MCH 20090301: I would think this should be any member list (non privilege... not just default)
if ( ( Group.getDefaultList().equals(f) ) && ( Group.this.hasComposite() ) ) {
throw new MemberAddException(E.GROUP_AMTC + ", " + Group.this.getName());
}
boolean doesntExist = true;
Membership membership = null;
try {
membership = Membership.internal_addImmediateMembership( GrouperSession.staticGrouperSession(), Group.this,
subj, f , uuid, startDate, endDate);
} catch (MemberAddAlreadyExistsException memberAddAlreadyExistsException) {
if (exceptionIfAlreadyMember) {
throw memberAddAlreadyExistsException;
}
doesntExist = false;
} catch (MembershipAlreadyExistsException membershipAlreadyExistsException) {
if (exceptionIfAlreadyMember) {
//convert to member add
throw new MemberAddAlreadyExistsException(membershipAlreadyExistsException);
}
doesntExist = false;
} catch (HookVeto hookVeto) {
//pass this through
throw hookVeto;
} catch (Exception exception) {
throw new RuntimeException(exception);
}
// if this is a wheel group then clear the wheel cache (granted if effective this wont work but cache lasts 10 seconds)
if (
(GrouperConfig.retrieveConfig().propertyValueBoolean(GrouperConfig.PROP_USE_WHEEL_GROUP, false) &&
StringUtils.equals(Group.this.getName(), GrouperConfig.retrieveConfig().propertyValueString( GrouperConfig.PROP_WHEEL_GROUP )))
|| (GrouperConfig.retrieveConfig().propertyValueBoolean("groups.wheel.readonly.use", false) &&
StringUtils.equals(Group.this.getName(), GrouperConfig.retrieveConfig().propertyValueString("groups.wheel.readonly.group")))
|| (GrouperConfig.retrieveConfig().propertyValueBoolean("groups.wheel.viewonly.use", false) &&
StringUtils.equals(Group.this.getName(), GrouperConfig.retrieveConfig().propertyValueString("groups.wheel.viewonly.group")))) {
PrivilegeHelper.wheelMemberCacheClear();
}
if (doesntExist) {
//this might be a wheel or a member of wheel... maybe there is a more efficient way to do this...
PrivilegeHelper.flushCache();
EVENT_LOG.groupAddMember(GrouperSession.staticGrouperSession(), Group.this.getName(), subj, f, sw);
RulesMembershipBean rulesMembershipBean = new RulesMembershipBean(membership, Group.this, subj);
//if we are in the default list, then fire a rule
if (StringUtils.equals(f.getUuid(), Group.getDefaultList().getUuid())) {
//fire rules directly connected to this membership add
RuleEngine.fireRule(RuleCheckType.membershipAdd, rulesMembershipBean);
//fire rules related to add in stem
RuleEngine.fireRule(RuleCheckType.membershipAddInFolder, rulesMembershipBean);
}
//fire rules related to subject assign in folder
RuleEngine.fireRule(RuleCheckType.subjectAssignInStem, rulesMembershipBean);
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.MEMBERSHIP_GROUP_ADD, "id",
membership == null ? null : membership.getUuid(), "fieldId", f.getUuid(),
"fieldName", f.getName(), "memberId", membership.getMemberUuid(),
"membershipType", membership.getType(),
"groupId", Group.this.getUuid(), "groupName", Group.this.getName());
auditEntry.setDescription("Added membership: group: " + Group.this.getName()
+ ", subject: " + subj.getSource().getId() + "." + subj.getId() + ", field: "
+ f.getName());
auditEntry.saveOrUpdate(true);
}
// just make sure again that the owner group isn't a composite,
// it could have been made into one while adding this membership..
// note that since the commit isn't done yet, this issue can still happen,
// but it would hopefully be much less likely..
if ((Group.getDefaultList().equals(f)) && (Group.this.hasComposite())) {
throw new IllegalStateException("Group (name=" + Group.this.getName() + ") turned into a composite while adding an immediate membership.");
}
}
sw.stop();
return doesntExist;
} catch (RuntimeException re) {
GrouperUtil.injectInException(re, errorMessageSuffix);
throw re;
}
}
});
} // public void addMember(subj, f)
/**
* Add an additional group type.
*
* @param type The {@link GroupType} to add.
* @throws GroupModifyException if unable to add type.
* @throws InsufficientPrivilegeException if subject not root-like.
* @throws SchemaException if attempting to add a system group type.
* @deprecated
*/
public void addType(GroupType type)
throws GroupModifyException,
InsufficientPrivilegeException,
SchemaException {
addType(type, true);
}
/**
* Add an additional group type.
*
* @param subj Check privileges for this {@link Subject}.
* @param f Check privileges on this {@link Field}.
* @return True if {@link Subject} can write {@link Field}, false otherwise.
* @throws IllegalArgumentException if null {@link Subject} or {@link Field}
* @throws SchemaException if invalid {@link Field}
* @since 1.0
*/
public boolean canWriteField(Subject subj, Field f)
throws IllegalArgumentException,
SchemaException
{
return this.internal_canWriteField(subj, f);
} // public boolean canWriteField(subj, f)
/**
* keep track of if we are in a delete so hooks can
*/
private static ThreadLocal threadLocalInGroupDelete = new InheritableThreadLocal();
/**
* see if we are in the middle of a delete (e.g. for hook)
* @return true if delete is occurring
*/
public static boolean deleteOccuring() {
Boolean deleteOccuring = threadLocalInGroupDelete.get();
if (deleteOccuring != null) {
return deleteOccuring;
}
return false;
}
/**
* Delete this group from the Groups Registry.
*
* try {
* g.delete();
* }
* catch (GroupDeleteException e0) {
* // Unable to delete group
* }
* catch (InsufficientPrivilegeException e1) {
* // Not privileged to delete this group
* }
*
* @throws GroupDeleteException
* @throws InsufficientPrivilegeException
*/
public void delete() throws GroupDeleteException, InsufficientPrivilegeException {
final String errorMessageSuffix = ", stem name: " + this.name + ", group extension: " + this.extension
+ ", group dExtension: " + this.displayExtension + ", uuid: " + this.uuid + ", ";
HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
StopWatch sw = new StopWatch();
sw.start();
GrouperSession.validate( GrouperSession.staticGrouperSession() );
if ( !PrivilegeHelper.canAdmin( GrouperSession.staticGrouperSession(), Group.this,
GrouperSession.staticGrouperSession().getSubject() ) ) {
throw new InsufficientPrivilegeException(
E.CANNOT_ADMIN + errorMessageSuffix);
}
try {
threadLocalInGroupDelete.set(true);
// ... And delete composite mship if it exists
if (Group.this.hasComposite()) {
Group.this.deleteCompositeMember();
}
// ... And delete composite mship if it exists if this group is a member
// GRP-1704: when deleting a group, delete any composites that is a member of
if (GrouperConfig.retrieveConfig().propertyValueBoolean("grouper.delete.compositeMembershipsOnGroupDelete", true)) {
for (Composite composite : GrouperUtil.nonNull(GrouperDAOFactory.getFactory().getComposite().findAsFactor( Group.this ))) {
composite.getOwnerGroup().deleteCompositeMember();
}
}
// ... And delete all memberships - as root
// Deletes (and saves) now happen within internal_deleteAllFieldType(). See GRP-254.
GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() {
public Object callback(GrouperSession grouperSession) throws GrouperSessionException {
Membership.internal_deleteAllFieldType(
GrouperSession.staticGrouperSession().internal_getRootSession(), Group.this, FieldType.LIST );
return null;
}
});
//delete any attributes on this group, this is done as root
GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() {
public Object callback(GrouperSession grouperSession) throws GrouperSessionException {
Set attributeAssigns = GrouperDAOFactory.getFactory().getAttributeAssign().findByOwnerGroupId(Group.this.getId());
Member member = Group.this.toMember();
if (member != null) {
attributeAssigns.addAll(GrouperDAOFactory.getFactory().getAttributeAssign().findByOwnerMemberId(member.getId()));
}
for (AttributeAssign attributeAssign : attributeAssigns) {
attributeAssign.delete();
}
return null;
}
});
// Delete privileges where this group is the member. This is done as root..
Subject groupSubject = Group.this.toSubject();
GrouperSession.staticGrouperSession().internal_getRootSession()
.getAccessResolver().revokeAllPrivilegesForSubject(groupSubject);
GrouperSession.staticGrouperSession().internal_getRootSession()
.getNamingResolver().revokeAllPrivilegesForSubject(groupSubject);
GrouperSession.staticGrouperSession().internal_getRootSession()
.getAttributeDefResolver().revokeAllPrivilegesForSubject(groupSubject);
// Revoke all access privs
// GRP-1193 - cant delete composite group
Group.this._revokeAllAccessPrivs();
//deletes.add(this); // ... And add the group last for good luck
String theName = Group.this.getName(); // Preserve name for logging
GrouperDAOFactory.getFactory().getGroup().delete(Group.this);
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = null;
if (Group.this.typeOfGroup == TypeOfGroup.entity) {
auditEntry = new AuditEntry(AuditTypeBuiltin.ENTITY_DELETE, "id",
Group.this.getUuid(), "name", Group.this.getName(), "parentStemId", Group.this.getParentUuid(),
"displayName", Group.this.getDisplayName(), "description", Group.this.getDescription());
auditEntry.setDescription("Deleted entity: " + Group.this.getName());
} else {
auditEntry = new AuditEntry(AuditTypeBuiltin.GROUP_DELETE, "id",
Group.this.getUuid(), "name", Group.this.getName(), "parentStemId", Group.this.getParentUuid(),
"displayName", Group.this.getDisplayName(), "description", Group.this.getDescription());
auditEntry.setDescription("Deleted group: " + Group.this.getName());
}
auditEntry.saveOrUpdate(true);
}
sw.stop();
EventLog.info(GrouperSession.staticGrouperSession(), M.GROUP_DEL + Quote.single(theName), sw);
} catch (InsufficientPrivilegeException eDAO) {
throw new GrouperException( eDAO );
} catch (GrouperDAOException eDAO) {
throw new GroupDeleteException( eDAO.getMessage() + errorMessageSuffix, eDAO );
} catch (RevokePrivilegeException eRP) {
throw new GroupDeleteException(eRP.getMessage() + errorMessageSuffix, eRP);
} catch (SchemaException eS) {
throw new GroupDeleteException(eS.getMessage() + errorMessageSuffix, eS);
} finally {
threadLocalInGroupDelete.remove();
}
return null;
}
});
}
/**
* Delete a group attribute.
*
* try {
* g.deleteAttribute(attribute);
* }
* catch (GroupModifyException e0) {
* // Unable to modify group
* }
* catch (InsufficientPrivilegeException e1) {
* // Not privileged to delete this attribute
* }
*
* @param attrName Delete this attribute.
* @throws AttributeNotFoundException
* @throws GroupModifyException
* @throws InsufficientPrivilegeException
* @deprecated
*/
public void deleteAttribute(final String attrName)
throws AttributeNotFoundException,
GroupModifyException,
InsufficientPrivilegeException {
this.deleteAttribute(attrName, false);
}
/**
* Delete a group attribute.
*
* try {
* g.deleteAttribute(attribute);
* }
* catch (GroupModifyException e0) {
* // Unable to modify group
* }
* catch (InsufficientPrivilegeException e1) {
* // Not privileged to delete this attribute
* }
*
* @param attrName Delete this attribute.
* @param failOnRequiredAttribute true if exception when attribute is required
* @throws AttributeNotFoundException
* @throws GroupModifyException
* @throws InsufficientPrivilegeException
* @deprecated
*/
public void deleteAttribute(final String attrName, final boolean failOnRequiredAttribute)
throws AttributeNotFoundException,
GroupModifyException,
InsufficientPrivilegeException {
if (failOnRequiredAttribute) {
throw new RuntimeException("Parameter failOnRequiredAttribute must be false.");
}
HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
try {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
StopWatch sw = new StopWatch();
sw.start();
NotNullOrEmptyValidator v = NotNullOrEmptyValidator.validate(attrName);
if (v.isInvalid()) {
throw new AttributeNotFoundException(E.INVALID_ATTR_NAME + attrName);
}
Group.this.getAttributesMap(false);
if (Group.this.attributes.containsKey(attrName)) {
AttributeAssignValue attribute = Group.this.attributes.get(attrName);
String val = attribute.getValueString(); // for logging
attribute.getAttributeAssign().getOwnerAttributeAssign().getAttributeDelegate().assertCanUpdateAttributeDefName(attribute.getAttributeAssign().getAttributeDefName());
// delete attribute assignment using new attribute framework
attribute.getAttributeAssign().delete();
Group.this.attributes.remove(attrName);
sw.stop();
EVENT_LOG.groupDelAttr(GrouperSession.staticGrouperSession(), Group.this.getName(), attrName, val, sw);
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.GROUP_ATTRIBUTE_DELETE, "id",
Group.this.getUuid(), "groupId", Group.this.getUuid(),
"groupName", Group.this.getName(), "fieldId", Group.this.getDescription(),
"fieldName", attrName, "value", val);
auditEntry.setDescription("Deleted group attribute: " + attrName + " on group: "
+ Group.this.getName() + " value: " + val);
auditEntry.saveOrUpdate(true);
}
}
else {
throw new AttributeNotFoundException("Attribute not exist: " + attrName);
}
}
catch (GrouperDAOException eDAO) {
throw new GroupModifyException( eDAO.getMessage(), eDAO );
}
catch (InsufficientPrivilegeException eIP) {
throw eIP;
}
catch (SchemaException eS) {
throw new AttributeNotFoundException(eS.getMessage(), eS);
}
return null;
}
});
} // public void deleteAttribute(attr)
/**
* Delete a {@link Composite} membership from this group.
*
* A composite group is composed of two groups and a set operator
* (stored in grouper_composites table)
* (e.g. union, intersection, etc). A composite group has no immediate members.
* All subjects in a composite group are effective members.
*
*
* try {
* g.deleteCompositeMember();
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete members
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete composite membership
* }
*
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @since 1.0
*/
public void deleteCompositeMember()
throws InsufficientPrivilegeException,
MemberDeleteException {
final StringBuilder errorMessageSuffix = new StringBuilder("group name: " + Group.this.name);
HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
try {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
StopWatch sw = new StopWatch();
sw.start();
String leftGroupName = null;
Composite composite = null;
try {
composite = Group.this.getComposite(true);
} catch (CompositeNotFoundException cnfe) {
GrouperUtil.injectInException(cnfe, errorMessageSuffix.toString());
throw new MemberDeleteException(E.GROUP_DCFC + ", " + cnfe.getMessage(), cnfe);
}
try {
leftGroupName = composite.getLeftGroup().getName();
} catch (GroupNotFoundException gnfe) {
leftGroupName = composite.getLeftFactorUuid();
}
String rightGroupName = null;
try {
rightGroupName = composite.getRightGroup().getName();
} catch (GroupNotFoundException gnfe) {
rightGroupName = composite.getRightFactorUuid();
}
errorMessageSuffix.append(", compositeType: " + composite.getTypeDb()
+ ", left group name: " + leftGroupName
+ ", right group name: " + rightGroupName);
if ( !Group.this.canWriteField( GrouperSession.staticGrouperSession().getSubject(), Group.getDefaultList() ) ) {
throw new InsufficientPrivilegeException();
}
GrouperDAOFactory.getFactory().getComposite().delete(composite);
EVENT_LOG.groupDelComposite( GrouperSession.staticGrouperSession(), composite, sw );
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.GROUP_COMPOSITE_DELETE, "id",
composite.getUuid(), "ownerId", Group.this.getUuid(), "ownerName", Group.this.getName(), "leftFactorId",
composite.getLeftFactorUuid(), "leftFactorName", leftGroupName, "rightFactorId", composite.getRightFactorUuid(),
"rightFactorName", rightGroupName, "type", composite.getTypeDb());
auditEntry.setDescription("Deleted composite: " + Group.this.getName() + " was "
+ leftGroupName + " " + composite.getTypeDb() + " " + rightGroupName);
auditEntry.saveOrUpdate(true);
}
sw.stop();
return null;
} catch (GrouperDAOException eDAO) {
GrouperUtil.injectInException(eDAO, errorMessageSuffix.toString());
throw new MemberDeleteException(eDAO.getMessage(), eDAO);
} catch (RuntimeException re) {
GrouperUtil.injectInException(re, errorMessageSuffix.toString());
throw re;
}
}
});
}
/**
* Delete a member from this group, and member must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(member);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param member Delete this {@link Member}
* @param exceptionIfAlreadyDeleted throw exception if already deleted
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @return false if it was already deleted, true if it wasnt already deleted
*/
public boolean deleteMember(Member member, boolean exceptionIfAlreadyDeleted)
throws InsufficientPrivilegeException, MemberDeleteException {
try {
return this.deleteMember(member, getDefaultList(), exceptionIfAlreadyDeleted);
}
catch (SchemaException eS) {
throw new MemberDeleteException(eS.getMessage(), eS);
}
}
/**
* Delete a member from this group, and member must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(member);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param member Delete this {@link Member}
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
*/
public void deleteMember(Member member)
throws InsufficientPrivilegeException, MemberDeleteException {
deleteMember(member, true);
}
/**
* Delete a member from this group, and member must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(m, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param member Delete this {@link Member}.
* @param f Delete subject from this {@link Field}.
* @param exceptionIfAlreadyDeleted
* @return false if it was already deleted, true if it wasnt already deleted
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @throws SchemaException
*/
public boolean deleteMember(Member member, Field f, boolean exceptionIfAlreadyDeleted)
throws InsufficientPrivilegeException, MemberDeleteException, SchemaException {
Subject lazySubject = new LazySubject(member);
return deleteMember(lazySubject, f, exceptionIfAlreadyDeleted);
}
/**
* Delete a member from this group, and member must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(m, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param member Delete this {@link Member}.
* @param f Delete subject from this {@link Field}.
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @throws SchemaException
*/
public void deleteMember(Member member, Field f)
throws InsufficientPrivilegeException, MemberDeleteException, SchemaException {
deleteMember(member, f, true);
}
/**
* Delete a subject from this group, and subject must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(subj);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param subj Delete this {@link Subject}
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
*/
public void deleteMember(Subject subj)
throws InsufficientPrivilegeException,
MemberDeleteException {
deleteMember(subj, true);
}
/**
* Delete a subject from this group, and subject must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(subj);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param subj Delete this {@link Subject}
* @param exceptionIfAlreadyDeleted
* @return false if it was already deleted, true if it wasnt already deleted
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
*/
public boolean deleteMember(Subject subj, boolean exceptionIfAlreadyDeleted)
throws InsufficientPrivilegeException,
MemberDeleteException
{
try {
return this.deleteMember(subj, getDefaultList(), exceptionIfAlreadyDeleted);
}
catch (SchemaException eS) {
throw new MemberDeleteException(eS.getMessage(), eS);
}
}
/**
* Delete a subject from this group, and subject must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(m, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param subj Delete this {@link Subject}.
* @param f Delete subject from this {@link Field}.
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @throws SchemaException
*/
public void deleteMember(Subject subj, Field f)
throws InsufficientPrivilegeException,
MemberDeleteException,
SchemaException {
deleteMember(subj, f, true);
}
/**
* Delete a subject from this group, and subject must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(m, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param subj Delete this {@link Subject}.
* @param f Delete subject from this {@link Field}.
* @param exceptionIfAlreadyDeleted true if an exception should be thrown
* if the member is already deleted
* @return false if it was already deleted, true if it wasnt already deleted
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @throws SchemaException
*/
public boolean deleteMember(final Subject subj, final Field f, final boolean exceptionIfAlreadyDeleted)
throws InsufficientPrivilegeException,
MemberDeleteException,
SchemaException {
return this.internal_deleteMember(subj, f, exceptionIfAlreadyDeleted, true);
}
/**
* Delete a subject from this group, and subject must be immediate
* member. Will not delete the effective membership.
*
* An immediate member is directly assigned to a group.
* A composite group has no immediate members. Note that a
* member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* A group can have potentially unlimited effective
* memberships
*
*
* try {
* g.deleteMember(m, f);
* }
* catch (InsufficientPrivilegeException eIP) {
* // Not privileged to delete this subject
* }
* catch (MemberDeleteException eMD) {
* // Unable to delete subject
* }
*
* @param subj Delete this {@link Subject}.
* @param f Delete subject from this {@link Field}.
* @param exceptionIfAlreadyDeleted true if an exception should be thrown
* if the member is already deleted
* @param checkSecurity false if should not check security
* @return false if it was already deleted, true if it wasnt already deleted
* @throws InsufficientPrivilegeException
* @throws MemberDeleteException
* @throws SchemaException
*/
public boolean internal_deleteMember(final Subject subj, final Field f, final boolean exceptionIfAlreadyDeleted, final boolean checkSecurity) {
final StopWatch sw = new StopWatch();
sw.start();
final String errorMessageSuffix = ", group name: " + this.name
+ ", subject: " + GrouperUtil.subjectToString(subj) + ", field: " + (f == null ? null : f.getName());
return (Boolean)HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
boolean notAlreadyDeleted = true;
try {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
// (12/2021) This constraint was added in 2007 without comment. Seems ok to remove it
//if ( !FieldType.LIST.equals( f.getType() ) ) {
// throw new SchemaException( E.FIELD_INVALID_TYPE + f.getType() );
//}
if (checkSecurity && !Group.this.canWriteField(f) ) {
GrouperValidator v = CanOptoutValidator.validate(Group.this, subj, f);
if (v.isInvalid()) {
throw new InsufficientPrivilegeException(errorMessageSuffix);
}
}
if ( (f.equals( Group.getDefaultList() ) ) && ( Group.this.hasComposite() ) ) {
throw new MemberDeleteException(E.GROUP_DMFC);
}
Membership membership = Membership.internal_delImmediateMembership(
GrouperSession.staticGrouperSession(), Group.this, subj, f );
sw.stop();
if (notAlreadyDeleted) {
//this might be a wheel or a member of wheel... maybe there is a more efficient way to do this...
PrivilegeHelper.flushCache();
EVENT_LOG.groupDelMember(GrouperSession.staticGrouperSession(),
Group.this.getName(), subj, f, sw);
//if we are in the default list, then fire a rule
if (StringUtils.equals(f.getUuid(), Group.getDefaultList().getUuid())) {
RulesMembershipBean rulesMembershipBean = new RulesMembershipBean(membership, Group.this, subj);
//fire rules directly connected to this membership remove
RuleEngine.fireRule(RuleCheckType.membershipRemove, rulesMembershipBean);
//fire rules related to remove in stem
RuleEngine.fireRule(RuleCheckType.membershipRemoveInFolder, rulesMembershipBean);
}
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.MEMBERSHIP_GROUP_DELETE, "id",
membership == null ? null : membership.getUuid(), "fieldId", f.getUuid(),
"fieldName", f.getName(), "memberId", membership.getMemberUuid(),
"membershipType", membership.getType(),
"groupId", Group.this.getUuid(), "groupName", Group.this.getName());
auditEntry.setDescription("Deleted membership: group: " + Group.this.getName()
+ ", subject: " + subj.getSource().getId() + "." + subj.getId() + ", field: "
+ f.getName());
auditEntry.saveOrUpdate(true);
}
}
} catch (GrouperDAOException eDAO) {
throw new MemberDeleteException( eDAO.getMessage() + ", " + errorMessageSuffix, eDAO );
} catch (MemberDeleteAlreadyDeletedException mdade) {
if (exceptionIfAlreadyDeleted) {
GrouperUtil.injectInException(mdade, errorMessageSuffix);
throw mdade;
}
notAlreadyDeleted = false;
}
return notAlreadyDeleted;
}
});
} // public void deleteMember(subj, f)
/**
* Delete a group type.
*
* @param type The {@link GroupType} to add.
* @throws GroupModifyException if unable to delete type.
* @throws InsufficientPrivilegeException if subject not root-like.
* @throws SchemaException if attempting to delete a system group type.
* @deprecated
*/
public void deleteType(final GroupType type)
throws GroupModifyException,
InsufficientPrivilegeException,
SchemaException {
final String typeString = type == null ? null : type.getName();
HibernateSession.callbackHibernateSession(
GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT, new HibernateHandler() {
public Object callback(HibernateHandlerBean hibernateHandlerBean)
throws GrouperDAOException {
try {
hibernateHandlerBean.getHibernateSession().setCachingEnabled(false);
StopWatch sw = new StopWatch();
sw.start();
if ( !Group.this.hasType(type, false) ) {
throw new GroupModifyException("does not have type: " + typeString);
}
if ( type.isSystemType() ) {
throw new SchemaException("cannot edit system group types: " + typeString);
}
if ( !PrivilegeHelper.canAdmin( GrouperSession.staticGrouperSession(), Group.this, GrouperSession.staticGrouperSession().getSubject() ) ) {
throw new InsufficientPrivilegeException(E.CANNOT_ADMIN);
}
Group.this.internal_getGroupTypeAssignments();
Group.this.getTypesDb();
AttributeAssign oldAssign = Group.this.typeAssignments.get(type.getName());
Group.this.types.remove(type.getName());
Group.this.typeAssignments.remove(type.getName());
Group.this.getAttributeDelegate().removeAttribute(type.getAttributeDefName());
// force refresh
Group.this.attributes = null;
Group.this.getAttributesDb();
if (!hibernateHandlerBean.isCallerWillCreateAudit()) {
AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.GROUP_TYPE_UNASSIGN, "id",
oldAssign.getId(), "groupId", Group.this.getUuid(),
"groupName", Group.this.getName(), "typeId", type.getUuid(), "typeName", type.getName());
auditEntry.setDescription("Unasssigned group type: " + name + ", typeId: " + type.getUuid()
+ ", to group: " + Group.this.getName() + ", groupId: " + Group.this.getUuid());
auditEntry.saveOrUpdate(true);
}
sw.stop();
EventLog.info(
GrouperSession.staticGrouperSession(),
M.GROUP_DELTYPE + Quote.single(Group.this.getName()) + " type=" + Quote.single( type.getName() ),
sw
);
return null;
} catch (GrouperDAOException eDAO) {
String msg = E.GROUP_TYPEDEL + type + ": ";
msg += eDAO.getMessage();
LOG.error(msg);
throw new GroupModifyException(msg, eDAO);
} catch (RuntimeException re) {
GrouperUtil.injectInException(re, "Problem with type: " + typeString);
throw re;
}
}
});
}
/**
* Get subjects with the ADMIN privilege on this group.
*
* Set admins = g.getAdmins();
*
* @return Set of subjects with ADMIN
* @throws GrouperException
*/
public Set getAdmins()
throws GrouperException
{
return GrouperSession.staticGrouperSession().getAccessResolver().getSubjectsWithPrivilege(this, AccessPrivilege.ADMIN);
}
/**
* get the value of an attribute, if not there return null
* @param attributeName
* @return the attribute value
* @deprecated use getAttributeValue()
*/
@Deprecated
public String getAttributeOrNull(String attributeName) {
try {
return this.getAttribute(attributeName);
} catch (AttributeNotFoundException anfe) {
return null;
}
}
/**
* if attribute or field name is a field name, call that getter with reflection.
* If not, then call getAttributeValue()
* @param attributeOrFieldName
* @param checkSecurity
* @param exceptionIfAttributeNotFound
* @return the value
* @deprecated
*/
public String getAttributeOrFieldValue(String attributeOrFieldName, boolean checkSecurity, boolean exceptionIfAttributeNotFound) {
if (INTERNAL_FIELD_ATTRIBUTES.contains(attributeOrFieldName)) {
return (String)GrouperUtil.fieldValue(this, attributeOrFieldName);
}
return this.getAttributeValue(attributeOrFieldName, checkSecurity, exceptionIfAttributeNotFound);
}
/**
* get the value of an attribute, if not there return the empty string.
* or exception if expected to be there.
*
* @param attributeName
* @param exceptionIfNotFound
* @param checkSecurity
* @return the attribute value or null if not there and not expecting exception.
* @deprecated
*/
public String getAttributeValue(String attributeName,
boolean checkSecurity, boolean exceptionIfNotFound) {
NotNullOrEmptyValidator v = NotNullOrEmptyValidator.validate(attributeName);
if (v.isInvalid()) {
throw new AttributeNotFoundException(E.INVALID_ATTR_NAME + attributeName);
}
//init
this.getAttributesMap(false);
AttributeAssignValue value = this.attributes.get(attributeName);
if (value == null) {
// Group does not have attribute. If attribute is not valid for Group,
// throw AttributeNotFoundException. Otherwise, return an empty string.
String attributeDefPrefix = GrouperConfig.retrieveConfig().propertyValueStringRequired("legacyAttribute.attributeDef.prefix");
AttributeDefName legacyAttribute = GrouperDAOFactory.getFactory().getAttributeDefName().findLegacyAttributeByName(attributeName, false);
if (legacyAttribute == null) {
throw new AttributeNotFoundException("Cant find attribute: " + attributeName);
}
AttributeDef legacyAttributeDef = legacyAttribute.getAttributeDef();
String groupTypeName = legacyAttributeDef.getExtension().substring(attributeDefPrefix.length());
AttributeAssign groupTypeAssignment = Group.this.internal_getGroupTypeAssignments().get(groupTypeName);
if (groupTypeAssignment == null) {
throw new AttributeNotFoundException("Group " + Group.this.getName() + " doesn't have attribute: " + attributeName);
}
if (exceptionIfNotFound) {
throw new AttributeNotFoundException("Cant find attribute value: " + attributeName);
}
return "";
}
if (checkSecurity) {
try {
value.getAttributeAssign().getOwnerAttributeAssign().getAttributeDelegate().assertCanReadAttributeDef(value.getAttributeAssign().getAttributeDef());
} catch (InsufficientPrivilegeException e) {
if (exceptionIfNotFound) {
throw new AttributeNotFoundException("Cant read attribute: " + attributeName);
}
return "";
} catch (AttributeDefNotFoundException e) {
if (exceptionIfNotFound) {
throw new AttributeNotFoundException("Cant read attribute: " + attributeName);
}
return "";
}
}
return StringUtils.defaultString(value.getValueString());
}
/**
* Get attribute value.
*
* try {
* String value = g.getAttribute(attribute);
* }
* catch (AttributeNotFoundException e) {
* // Group doesn't have attribute
* }
*
* @param attr Get value of this attribute.
* @return Attribute value. or throw AttributeNotFoundException if not there.
* The value will be the emprty string if it is null
* @throws AttributeNotFoundException
* @Deprecated use getAttributeValue
*/
@Deprecated
public String getAttribute(String attr)
throws AttributeNotFoundException {
return getAttributeValue(attr, false, false);
}
/**
* Get {@link Composite} {@link Member}s of this group.
*
* A composite group is composed of two groups and a set operator
* (stored in grouper_composites table)
* (e.g. union, intersection, etc). A composite group has no immediate members.
* All subjects in a composite group are effective members.
*
*
* Set members = g.getCompositeMembers();
*
* @param queryOptions
* @return A set of {@link Member} objects.
* @since 1.0
*/
public Set getCompositeMembers(QueryOptions queryOptions) {
return getCompositeMembers(Group.getDefaultList(), null, queryOptions);
} // public Set getCompositeMembers()
/**
* @param attr
* @return the value
*/
@SuppressWarnings("unused")
private String _internal_getAttributeBuiltIn(String attr) {
if (GrouperConfig.retrieveConfig().propertyValueBoolean("groups.allow.attribute.access.1.4", false)) {
if (StringUtils.equals(FIELD_NAME, attr)) {
return this.getName();
}
if (StringUtils.equals(FIELD_EXTENSION, attr)) {
return this.getExtension();
}
if (StringUtils.equals(FIELD_DISPLAY_NAME, attr)) {
return this.getDisplayName();
}
if (StringUtils.equals(FIELD_DISPLAY_EXTENSION, attr)) {
return this.getDisplayExtension();
}
if (StringUtils.equals(FIELD_DESCRIPTION, attr)) {
return this.getDescription();
}
throw new RuntimeException("Not expecting attribute: " + attr);
}
throw new RuntimeException("Cannot access built in attribute: " + attr + " from getAttributes anymore, " +
"use getter directly (e.g. getName(), getDisplayName()). Or you can enable this (deprecated) with " +
"grouper.properties setting groups.allow.attribute.access.1.4=true");
}
/**
* Get all attributes and values.
*
* Map attributes = g.getAttributes();
*
* @return A map of attributes and values.
* @deprecated use getAttributesMap
*/
@Deprecated
public Map getAttributes() {
//init
Map results = this.getAttributesMap(true);
Map map = new HashMap();
for (String key : results.keySet()) {
map.put(key, results.get(key).getValue());
}
return map;
//Subject currentSubject = GrouperSession.staticGrouperSession().getSubject();
//if (GrouperConfig.retrieveConfig().propertyValueBoolean("groups.allow.attribute.access.1.4", false)) {
//
// boolean canReadGroup = this.hasRead(currentSubject);
// boolean canViewGroup = this.hasView(currentSubject);
//
// if (canViewGroup) {
// {
// String theName = this.getName();
// if (!StringUtils.isBlank(theName)) {
// filtered.put("name", theName);
// }
// }
// {
// String theDisplayName = this.getDisplayName();
// if (!StringUtils.isBlank(theDisplayName)) {
// filtered.put("displayName", theDisplayName);
// }
// }
// {
// String theExtension = this.getExtension();
// if (!StringUtils.isBlank(theExtension)) {
// filtered.put("extension", theExtension);
// }
// }
// {
// String theDisplayExtension = this.getDisplayExtension();
// if (!StringUtils.isBlank(theDisplayExtension)) {
// filtered.put("displayExtension", theDisplayExtension);
// }
// }
// }
// if (canReadGroup) {
// {
// String theDescription = this.getDescription();
// if (!StringUtils.isBlank(theDescription)) {
// filtered.put("description", theDescription);
// }
// }
// }
//}
} // public Map getAttributes()
/**
* Get {@link Composite} {@link Member}s of this group.
*
* A composite group is composed of two groups and a set operator
* (stored in grouper_composites table)
* (e.g. union, intersection, etc). A composite group has no immediate members.
* All subjects in a composite group are effective members.
*
*
* Set members = g.getCompositeMembers();
*
* @return A set of {@link Member} objects.
* @since 1.0
*/
public Set getCompositeMembers() {
return this.getCompositeMembers(null);
} // public Set getCompositeMembers()
/**
* Get {@link Composite} {@link Membership}s of this group.
*
* A composite group is composed of two groups and a set operator
* (stored in grouper_composites table)
* (e.g. union, intersection, etc). A composite group has no immediate members.
* All subjects in a composite group are effective members.
*
* A membership is the object which represents a join of member
* and group. Has metadata like type and creator,
* and, if an effective membership, the parent membership
*
*
* Set mships = g.getCompositeMembers();
*
* @return A set of {@link Membership} objects.
* @since 1.0
*/
public Set getCompositeMemberships() {
return MembershipFinder.internal_findAllByGroupOwnerAndFieldAndType(
GrouperSession.staticGrouperSession(), this, Group.getDefaultList(), MembershipType.COMPOSITE.getTypeString()
);
} // public Set getCompositeMemberships()
/**
* Get subject that created this group.
*
* // Get creator of this group.
* try {
* Subject creator = g.getCreateSubject();
* }
* catch (SubjectNotFoundException e) {
* // Couldn't find subject
* }
*
* @return {@link Subject} that created this group.
* @throws SubjectNotFoundException
*/
public Subject getCreateSubject()
throws SubjectNotFoundException
{
if ( this.subjectCache.containsKey(KEY_CREATOR) ) {
return this.subjectCache.get(KEY_CREATOR);
}
try {
// when called from "GrouperSubject" there is no attached session
Member _m = GrouperDAOFactory.getFactory().getMember().findByUuid( this.getCreatorUuid(), true );
this.subjectCache.put(
KEY_CREATOR, SubjectFinder.findByIdAndSource( _m.getSubjectId(), _m.getSubjectSourceId() , true)
);
return this.subjectCache.get(KEY_CREATOR);
}
catch (MemberNotFoundException eMNF) {
throw new SubjectNotFoundException( eMNF.getMessage(), eMNF );
}
catch (SourceUnavailableException eSU) {
throw new SubjectNotFoundException( eSU.getMessage(), eSU );
}
catch (SubjectNotUniqueException eSNU) {
throw new SubjectNotFoundException( eSNU.getMessage(), eSNU );
}
} // public Subject getCreateSubject()
/**
* Get creation time for this group.
*
* // Get create time.
* Date created = g.getCreateTime();
*
* @return {@link Date} that this group was created.
*/
public Date getCreateTime() {
return new Date(this.getCreateTimeLong());
} // public Date getCreateTime()
/**
* Get group description.
*
* String description = g.getDescription();
*
* @return Group's description or an empty string if no value set.
*/
public String getDescription() {
return GrouperUtil.defaultString(this.description);
}
/**
* Get group description for hibernate.
* @return Group's description or an empty string if no value set.
*/
public String getDescriptionDb() {
return this.description;
}
/**
* list of internal field attributes, access with method so it can lazy load
*/
public static final Set INTERNAL_FIELD_ATTRIBUTES = Collections.unmodifiableSet(
GrouperUtil.toSet(FIELD_DESCRIPTION, FIELD_NAME, FIELD_EXTENSION,
FIELD_DISPLAY_EXTENSION, FIELD_DISPLAY_NAME));
/**
* see if field attribute (name, description, extension, displayName, displayExtension)
* @param attributeName
* @return true if so
*/
public static boolean _internal_fieldAttribute(String attributeName) {
return INTERNAL_FIELD_ATTRIBUTES.contains(attributeName);
}
/**
* Get group displayExtension.
*
* String displayExtn = g.getDisplayExtension();
*
* @return Gruop displayExtension.
* @throws GrouperException
*/
public String getDisplayExtension() {
// We don't validate privs here because if one has retrieved a group then one
// has at least VIEW.
String val = this.displayExtension;
if ( val == null || GrouperConfig.EMPTY_STRING.equals(val) ) {
// A group without this attribute is VERY faulty
LOG.fatal(E.GROUP_NODE);
throw new GrouperException(E.GROUP_NODE);
}
return val;
} // public String getDisplayExtension()
/**
* Get group displayName.
*
* String displayName = g.getDisplayName();
*
* @return Group displayName.
* @throws GrouperException
*/
public String getDisplayName()
throws GrouperException
{
// We don't validate privs here because if one has retrieved a group then one
// has at least VIEW.
String val = this.displayName;
if ( val == null || GrouperConfig.EMPTY_STRING.equals(val) ) {
// A group without this attribute is VERY faulty
LOG.fatal(E.GROUP_NODN);
throw new GrouperException(E.GROUP_NODN);
}
return val;
} // public String getDisplayName()
/**
* Get effective members of this group.
*
* An effective member has an indirect membership to a group
* (e.g. in a group within a group). All subjects in a
* composite group are effective members (since the composite
* group has two groups and a set operator and no other immediate
* members). Note that a member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* 'group within a group' can be nested to any level so long as it does
* not become circular. A group can have potentially unlimited effective
* memberships
*
*
* Set effectives = g.getEffectiveMembers();
*
* @return A set of {@link Member} objects.
* @throws GrouperException
*/
public Set getEffectiveMembers()
throws GrouperException
{
try {
return this.getEffectiveMembers(getDefaultList());
}
catch (SchemaException eS) {
// If we don't have "members" we have serious issues
String msg = E.GROUP_NODEFAULTLIST + eS.getMessage();
LOG.fatal(msg);
throw new GrouperException(msg, eS);
}
} // public Set getEffectiveMembership()
/**
* Get effective members of this group.
*
* An effective member has an indirect membership to a group
* (e.g. in a group within a group). All subjects in a
* composite group are effective members (since the composite
* group has two groups and a set operator and no other immediate
* members). Note that a member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* 'group within a group' can be nested to any level so long as it does
* not become circular. A group can have potentially unlimited effective
* memberships
*
*
* Set effectives = g.getEffectiveMembers(f);
*
* @param f Get members in this list field.
* @return A set of {@link Member} objects.
* @throws SchemaException
*/
public Set getEffectiveMembers(Field f)
throws SchemaException
{
return this.getEffectiveMembers(f, null);
} // public Set getEffectiveMembers(f)
/**
* Get effective members of this group.
*
* An effective member has an indirect membership to a group
* (e.g. in a group within a group). All subjects in a
* composite group are effective members (since the composite
* group has two groups and a set operator and no other immediate
* members). Note that a member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* 'group within a group' can be nested to any level so long as it does
* not become circular. A group can have potentially unlimited effective
* memberships
*
*
* Set effectives = g.getEffectiveMembers(f);
*
* @param f Get members in this list field.
* @param queryOptions
* @return A set of {@link Member} objects.
* @throws SchemaException
*/
public Set getEffectiveMembers(Field f, QueryOptions queryOptions)
throws SchemaException
{
return getEffectiveMembers(f, null, queryOptions);
} // public Set getEffectiveMembers(f)
/**
* Get effective members of this group.
*
* An effective member has an indirect membership to a group
* (e.g. in a group within a group). All subjects in a
* composite group are effective members (since the composite
* group has two groups and a set operator and no other immediate
* members). Note that a member can have 0 to 1 immediate memberships
* to a single group, and 0 to many effective memberships to a group.
* 'group within a group' can be nested to any level so long as it does
* not become circular. A group can have potentially unlimited effective
* memberships
*
*
* Set effectives = g.getEffectiveMembers(f);
*
* @param f Get members in this list field.
* @param sources sources to filter by, or null for all
* @param queryOptions
* @return A set of {@link Member} objects.
* @throws SchemaException
*/
public Set getEffectiveMembers(Field f, Set