blob: 811319f50998c53a056bdc0561d62126f1921e85 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://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 org.apache.directory.fortress.core.model;
import org.apache.directory.fortress.core.util.PropUtil;
import jakarta.xml.bind.annotation.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* All entities (User, Role, Permission, Policy, SDSet, etc...) are used to carry data between Fortress's
* layers starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
* (3) DAO layer where persistence with the LDAP server occurs. The clients must instantiate an Fortress entity before use
* and must provide enough information to uniquely identity target record for reads.
* <p>
* <h4>Group Schema</h4>
* <p>
* The Fortress Group entity is a composite of 2 different LDAP Schema object classes:
* <p>
* 1. groupOfNames Structural Object Class is used to manage groups within LDAP.
* <pre>
* ------------------------------------------
* objectClasses: ( 2.5.6.9 NAME 'groupOfNames'
* DESC 'RFC2256: a group of names (DNs)' SUP top STRUCTURAL
* MUST (
* member $ cn )
* MAY
* ( businessCategory $ seeAlso $ owner $ ou $ o $ description
* )
* )
* ------------------------------------------
* </pre>
* <p>
* 2. configGroup STRUCTURAL Object Class is used to store groups and their relationships to users or roles.
* <pre>
* ------------------------------------------
* LDAP Configuration Group Structural Object Class
* objectClass ( ftObId:8
* NAME 'configGroup'
* DESC 'LDAP Configuration Group'
* S
* SUP groupOfNames
* MUST (
* configProtocol $
* ftType
* )
* MAY configParameter
* )
* ------------------------------------------
* </pre>
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@XmlRootElement(name = "fortGroup")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "group", propOrder =
{
"name",
"description",
"protocol",
"members",
"props",
"type",
"roles"
})
public class Group extends FortEntity implements Serializable
{
private static final long serialVersionUID = 1L;
private String name;
private String description;
private String protocol;
private List<String> members;
private Props props = new Props();
@XmlTransient
private boolean memberDn;
private Type type;
/**
* Auxiliary field used to store roles in UserRole format.
*/
@XmlElement( nillable = true )
private List<UserRole> roles = new ArrayList<>();
/**
* enum for User or Role data sets. Both nodes may be stored in the same LDAP container.
*/
@XmlType(name = "groupType")
@XmlEnum
public enum Type
{
/**
* Entry contains a set of Users.
*/
USER,
/**
* Entry contains a set of Roles.
*/
ROLE
}
/**
* Get the required type of Group - 'USER' Or 'ROLE'.
*
* @return type that determines what node maps to.
*/
public Type getType()
{
return type;
}
/**
* Set the required type of Group - 'USER' Or 'ROLE'.
*
* @param type determines what set the node contains.
*/
public void setType( Type type )
{
this.type = type;
}
/**
* Default constructor used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} defaults to type USER.
*/
public Group()
{
type = Type.USER;
}
/**
* Constructor for base type.
*/
public Group( Type type )
{
this.type = type;
}
/**
* Generate instance of group to be loaded as ldap object.
*
* @param name maps to 'cn' attribute in group object class.
*/
public Group( String name )
{
this.name = name;
type = Type.USER;
}
/**
* Generate instance of group to be loaded as ldap object with node type.
*
* @param name maps to 'cn' attribute in group object class.
*/
public Group( String name, Type type )
{
this.name = name;
this.type = type;
}
/**
* Generate instance of group to be loaded as ldap object.
*
* @param name maps to 'cn' attribute in group object class.
* @param description maps to 'description' attribute in group object class.
*/
public Group( String name, String description )
{
this.name = name;
this.description = description;
type = Type.USER;
}
/**
* Generate instance of group to be loaded as ldap object with node type.
*
* @param name maps to 'cn' attribute in group object class.
* @param description maps to 'description' attribute in group object class.
*/
public Group( String name, String description, Type type )
{
this.name = name;
this.description = description;
this.type = type;
}
/**
* Get the second level qualifier on the domain component. This attribute is required.
*
* @return name maps to 'dcObject' object class.
*/
public String getName()
{
return name;
}
/**
* Set the second level qualifier on the domain component. This attribute is required.
*
* @param name maps to 'dcObject' object class.
*/
public void setName( String name )
{
this.name = name;
}
/**
* Get the description for the domain component. This value is not required or constrained
* but is validated on reasonability.
*
* @return field maps to 'o' attribute on 'dcObject'.
*/
public String getDescription()
{
return description;
}
/**
* Set the description for the domain component. This value is not required or constrained
* but is validated on reasonability.
*
* @param description maps to 'o' attribute on 'dcObject'.
*/
public void setDescription( String description )
{
this.description = description;
}
/**
* Get protocol qualifier for this entity.
*
* @return protocol.
*/
public String getProtocol()
{
return protocol;
}
/**
* Set the protocol qualifier for this entity.
*
* @param protocol contains protocol qualifier for this entity.
*/
public void setProtocol( String protocol )
{
this.protocol = protocol;
}
/**
* Add a single userId as member of this entity.
*
* @param userId
*/
public void setMember( String userId )
{
if ( members == null )
{
members = new ArrayList<>();
}
members.add( userId );
}
/**
* Return the members
*
* @return List of type String containing userIds.
*/
public List<String> getMembers()
{
return members;
}
/**
* Set a member on this entity using a comma delimited String.
*
* @param members String contains one or more userids in comma delimited format.
*/
public void setMembersWithCsv( String members )
{
if ( members != null )
{
StringTokenizer tkn = new StringTokenizer( members, "," );
if ( tkn.countTokens() > 0 )
{
while ( tkn.hasMoreTokens() )
{
String member = tkn.nextToken();
setMember( member );
}
}
}
}
/**
* Set members onto this entity using a List of userIds.
*
* @param members List of type String contains userIds to be associated as members of this group.
*/
public void setMembers( List<String> members )
{
this.members = members;
}
/**
* Add name/value pair to list of properties associated with PermObj. These values are not constrained by Fortress.
* Properties are optional.
*
* @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
* @param value
*/
public void addProperty( String key, String value )
{
Props.Entry entry = new Props.Entry();
entry.setKey( key );
entry.setValue( value );
this.props.getEntry().add( entry );
}
/**
* Get a name/value pair attribute from list of properties associated with PermObj. These values are not constrained by Fortress.
* Properties are optional.
*
* @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
* @return value containing name/value pair that maps to 'ftProps' attribute in 'ftProperties' aux object class.
*/
public String getProperty( String key )
{
List<Props.Entry> props = this.props.getEntry();
Props.Entry keyObj = new Props.Entry();
keyObj.setKey( key );
String value = null;
int indx = props.indexOf( keyObj );
if ( indx != -1 )
{
Props.Entry entry = props.get( props.indexOf( keyObj ) );
value = entry.getValue();
}
return value;
}
/**
* Replace teh collection of name/value pairs to attributes associated with Group entity. These values are not constrained by Fortress.
* Properties are optional.
*
* @param properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
*/
public void setProperties( Properties properties )
{
if ( properties != null )
{
// reset the existing properties stored in this entity.
props = new Props();
for ( Enumeration<?> e = properties.propertyNames(); e.hasMoreElements(); )
{
// This LDAP attr is stored as a name-value pair separated by a ':'.
String key = ( String ) e.nextElement();
String val = properties.getProperty( key );
addProperty( key, val );
}
}
}
/**
* Add new collection of name=value pairs to attributes associated with Group. These values are not constrained by Fortress.
* Properties are optional.
*
* @param properties contains name=value pairs that are comma delmited.
*/
public void setPropertiesWithCsv( String properties )
{
setProperties( PropUtil.getProperties( properties, '=', "," ) );
}
/**
* Return the collection of name/value pairs to attributes associated with PermObj. These values are not constrained by Fortress.
* Properties are optional.
*
* @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
*/
public Properties getProperties()
{
Properties properties = null;
List<Props.Entry> props = this.props.getEntry();
if ( props.size() > 0 )
{
properties = new Properties();
for ( Props.Entry entry : props )
{
String key = entry.getKey();
String val = entry.getValue();
properties.setProperty( key, val );
}
}
return properties;
}
public List<String> getPropList()
{
List<Props.Entry> props = this.props.getEntry();
List<String> propList = null;
if ( props.size() > 0 )
{
propList = new ArrayList<>();
for ( Props.Entry entry : props )
{
String key = entry.getKey();
String val = entry.getValue();
String prop = key + "=" + val;
propList.add( prop );
}
}
return propList;
}
/**
* Gets the value of the Props property. This method is used by Fortress Core and Rest and should not be called by external programs.
*
* @return {@link Props }
*
*/
public Props getProps()
{
return props;
}
/**
* Sets the value of the Props property. This method is used by Fortress Core and Rest and should not be called by external programs.
*
* @param props
* allowed object is
* {@link Props }
*
*/
public void setProps( Props props )
{
this.props = props;
}
/**
* Set if userDn's are loaded in dn format.
*
* @return true indicates members are in dn format.
*/
public boolean isMemberDn()
{
return memberDn;
}
/**
* Set to 'true' if members are in dn format.
*
* @param memberDn boolean value, set to 'true' if distinguished name (dn) format, 'false' if relative distinguished name (rdn) format.
*/
public void setMemberDn( boolean memberDn )
{
this.memberDn = memberDn;
}
/**
* List of roles for given groups if they were populated. Empty list otherwise.
* @return
*/
public List<UserRole> getRoles() {
return roles;
}
/**
* Setter for auxiliary 'roles' field.
* @param roles list of roles to be set
*/
public void setRoles(List<UserRole> roles) {
this.roles = roles;
}
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
Group group = ( Group ) o;
if ( name == null )
{
return false;
}
return name.equals( group.name );
}
@Override
public int hashCode()
{
int result = name.hashCode();
result = 31 * result + ( description != null ? description.hashCode() : 0 );
result = 31 * result + ( protocol != null ? protocol.hashCode() : 0 );
result = 31 * result + ( members != null ? members.hashCode() : 0 );
result = 31 * result + ( props != null ? props.hashCode() : 0 );
return result;
}
@Override
public String toString()
{
return "Group{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
}