001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.core.datatype.adapter.DateAdapter; 004import gov.nist.secauto.metaschema.core.datatype.adapter.StringAdapter; 005import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; 006import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; 007import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLineAdapter; 008import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; 009import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultilineAdapter; 010import gov.nist.secauto.metaschema.core.model.IBoundObject; 011import gov.nist.secauto.metaschema.core.model.IMetaschemaData; 012import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior; 013import gov.nist.secauto.metaschema.core.model.constraint.IConstraint; 014import gov.nist.secauto.metaschema.core.util.ObjectUtils; 015import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValue; 016import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValues; 017import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints; 018import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly; 019import gov.nist.secauto.metaschema.databind.model.annotations.BoundField; 020import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag; 021import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; 022import gov.nist.secauto.metaschema.databind.model.annotations.IndexHasKey; 023import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique; 024import gov.nist.secauto.metaschema.databind.model.annotations.KeyField; 025import gov.nist.secauto.metaschema.databind.model.annotations.Matches; 026import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 027import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints; 028import java.lang.Override; 029import java.lang.String; 030import java.util.LinkedList; 031import java.util.List; 032import java.util.UUID; 033import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 034import org.apache.commons.lang3.builder.ToStringStyle; 035 036/** 037 * A defined component that can be part of an implemented system. 038 */ 039@MetaschemaAssembly( 040 formalName = "Component", 041 description = "A defined component that can be part of an implemented system.", 042 name = "defined-component", 043 moduleClass = OscalComponentDefinitionModule.class, 044 remarks = "Components may be products, services, APIs, policies, processes, plans, guidance, standards, or other tangible items that enable security and/or privacy.\n" 045 + "\n" 046 + "The `type` indicates which of these component types is represented.\n" 047 + "\n" 048 + "A group of components may be aggregated into a `capability`. For example, an account management capability that consists of an account management process, and a Lightweight Directory Access Protocol (LDAP) software implementation.\n" 049 + "\n" 050 + "Capabilities are expressed by combining one or more components.", 051 valueConstraints = @ValueConstraints(allowedValues = {@AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "version", description = "The version of the component."), @AllowedValue(value = "patch-level", description = "The specific patch level of the component."), @AllowedValue(value = "model", description = "The model of the component."), @AllowedValue(value = "release-date", description = "The date the component was released, such as a software release date or policy publication date."), @AllowedValue(value = "validation-type", description = "Used with component-type='validation' to provide a well-known name for a kind of validation."), @AllowedValue(value = "validation-reference", description = "Used with component-type='validation' to indicate the validating body's assigned identifier for their validation of this component."), @AllowedValue(value = "asset-type", description = "Simple indication of the asset's function, such as Router, Storage Array, DNS Server."), @AllowedValue(value = "asset-id", description = "An organizationally specific identifier that is used to uniquely identify a logical or tangible item by the organization that owns the item."), @AllowedValue(value = "asset-tag", description = "An asset tag assigned by the organization responsible for maintaining the logical or tangible item."), @AllowedValue(value = "public", description = "Identifies whether the asset is publicly accessible (yes/no)"), @AllowedValue(value = "virtual", description = "Identifies whether the asset is virtualized (yes/no)"), @AllowedValue(value = "vlan-id", description = "Virtual LAN identifier of the asset."), @AllowedValue(value = "network-id", description = "The network identifier of the asset."), @AllowedValue(value = "label", description = "A human-readable label for the parent context."), @AllowedValue(value = "sort-id", description = "An alternative identifier, whose value is easily sortable among other such values in the document."), @AllowedValue(value = "baseline-configuration-name", description = "The name of the baseline configuration for the asset."), @AllowedValue(value = "allows-authenticated-scan", description = "Can the asset be check with an authenticated scan? (yes/no)"), @AllowedValue(value = "function", description = "The function provided by the asset for the system.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "link/@rel", allowOthers = true, values = {@AllowedValue(value = "depends-on", description = "A reference to another component that this component has a dependency on."), @AllowedValue(value = "validation", description = "A reference to another component of component-type=validation, that is a validation (e.g., FIPS 140-2) for this component"), @AllowedValue(value = "proof-of-compliance", description = "A pointer to a validation record (e.g., FIPS 140-2) or other compliance information."), @AllowedValue(value = "baseline-template", description = "A reference to the baseline template used to configure the asset."), @AllowedValue(value = "uses-service", description = "This service is used by the referenced component identifier."), @AllowedValue(value = "system-security-plan", description = "A link to the system security plan of the external system."), @AllowedValue(value = "uses-network", description = "This component uses the network provided by the identified network component.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "responsible-role/@role-id|control-implementation/implemented-requirement/responsible-role/@role-id|control-implementation/implemented-requirement/statement/responsible-role/@role-id", allowOthers = true, values = {@AllowedValue(value = "asset-owner", description = "Accountable for ensuring the asset is managed in accordance with organizational policies and procedures."), @AllowedValue(value = "asset-administrator", description = "Responsible for administering a set of assets."), @AllowedValue(value = "security-operations", description = "Members of the security operations center (SOC)."), @AllowedValue(value = "network-operations", description = "Members of the network operations center (NOC)."), @AllowedValue(value = "incident-response", description = "Responsible for responding to an event that could lead to loss of, or disruption to, an organization's operations, services or functions."), @AllowedValue(value = "help-desk", description = "Responsible for providing information and support to users."), @AllowedValue(value = "configuration-management", description = "Responsible for the configuration management processes governing changes to the asset."), @AllowedValue(value = "maintainer", description = "Responsible for the creation and maintenance of a component."), @AllowedValue(value = "provider", description = "Organization responsible for providing the component, if this is different from the \"maintainer\" (e.g., a reseller).")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='asset-type']/@value", allowOthers = true, values = {@AllowedValue(value = "operating-system", description = "System software that manages computer hardware, software resources, and provides common services for computer programs."), @AllowedValue(value = "database", description = "An electronic collection of data, or information, that is specially organized for rapid search and retrieval."), @AllowedValue(value = "web-server", description = "A system that delivers content or services to end users over the Internet or an intranet."), @AllowedValue(value = "dns-server", description = "A system that resolves domain names to internet protocol (IP) addresses."), @AllowedValue(value = "email-server", description = "A computer system that sends and receives electronic mail messages."), @AllowedValue(value = "directory-server", description = "A system that stores, organizes and provides access to directory information in order to unify network resources."), @AllowedValue(value = "pbx", description = "A private branch exchange (PBX) provides a a private telephone switchboard."), @AllowedValue(value = "firewall", description = "A network security system that monitors and controls incoming and outgoing network traffic based on predetermined security rules."), @AllowedValue(value = "router", description = "A physical or virtual networking device that forwards data packets between computer networks."), @AllowedValue(value = "switch", description = "A physical or virtual networking device that connects devices within a computer network by using packet switching to receive and forward data to the destination device."), @AllowedValue(value = "storage-array", description = "A consolidated, block-level data storage capability."), @AllowedValue(value = "appliance", description = "A physical or virtual machine that centralizes hardware, software, or services for a specific purpose.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='allows-authenticated-scan']/@value", values = {@AllowedValue(value = "yes", description = "The component allows an authenticated scan."), @AllowedValue(value = "no", description = "The component does not allow an authenticated scan.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='virtual']/@value", values = {@AllowedValue(value = "yes", description = "The component is virtualized."), @AllowedValue(value = "no", description = "The component is not virtualized.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='public']/@value", values = {@AllowedValue(value = "yes", description = "The component is publicly accessible."), @AllowedValue(value = "no", description = "The component is not publicly accessible.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='implementation-point']/@value", values = {@AllowedValue(value = "internal", description = "The component is implemented within the system boundary."), @AllowedValue(value = "external", description = "The component is implemented outside the system boundary.")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "(.)[@type='software']/prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = @AllowedValue(value = "software-identifier", description = "If a \"software\" component-type, the identifier, such as a SWID tag, for the software component.")), @AllowedValues(level = IConstraint.Level.ERROR, target = "(.)[@type='service']/link/@rel", allowOthers = true, values = {@AllowedValue(value = "provided-by", description = "This service is provided by the referenced component identifier."), @AllowedValue(value = "used-by", description = "This service is used by the referenced component identifier.")})}, indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, target = "prop[@name='physical-location']", indexName = "index-metadata-location-uuid", keyFields = @KeyField(target = "@value")), matches = {@Matches(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='inherited-uuid']/@value", typeAdapter = UuidAdapter.class), @Matches(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='release-date']/@value", typeAdapter = DateAdapter.class)}), 052 modelConstraints = @AssemblyConstraints(unique = @IsUnique(id = "unique-defined-component-responsible-role", level = IConstraint.Level.ERROR, target = "responsible-role", keyFields = @KeyField(target = "@role-id"), remarks = "Since `responsible-role` associates multiple `party-uuid` entries with a single `role-id`, each role-id must be referenced only once.")) 053) 054public class DefinedComponent implements IBoundObject { 055 private final IMetaschemaData __metaschemaData; 056 057 /** 058 * "Provides a globally unique means to identify a given component." 059 */ 060 @BoundFlag( 061 formalName = "Component Identifier", 062 description = "Provides a globally unique means to identify a given component.", 063 name = "uuid", 064 required = true, 065 typeAdapter = UuidAdapter.class 066 ) 067 private UUID _uuid; 068 069 /** 070 * "A category describing the purpose of the component." 071 */ 072 @BoundFlag( 073 formalName = "Component Type", 074 description = "A category describing the purpose of the component.", 075 name = "type", 076 required = true, 077 typeAdapter = StringAdapter.class, 078 valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = {@AllowedValue(value = "interconnection", description = "A connection to something outside this system."), @AllowedValue(value = "software", description = "Any software, operating system, or firmware."), @AllowedValue(value = "hardware", description = "A physical device."), @AllowedValue(value = "service", description = "A service that may provide APIs."), @AllowedValue(value = "policy", description = "An enforceable policy."), @AllowedValue(value = "physical", description = "A tangible asset used to provide physical protections or countermeasures."), @AllowedValue(value = "process-procedure", description = "A list of steps or actions to take to achieve some end result."), @AllowedValue(value = "plan", description = "An applicable plan."), @AllowedValue(value = "guidance", description = "Any guideline or recommendation."), @AllowedValue(value = "standard", description = "Any organizational or industry standard."), @AllowedValue(value = "validation", description = "An external assessment performed on some other component, that has been validated by a third-party.")})) 079 ) 080 private String _type; 081 082 @BoundField( 083 formalName = "Component Title", 084 description = "A human readable name for the component.", 085 useName = "title", 086 minOccurs = 1, 087 typeAdapter = MarkupLineAdapter.class 088 ) 089 private MarkupLine _title; 090 091 @BoundField( 092 formalName = "Component Description", 093 description = "A description of the component, including information about its function.", 094 useName = "description", 095 minOccurs = 1, 096 typeAdapter = MarkupMultilineAdapter.class 097 ) 098 private MarkupMultiline _description; 099 100 @BoundField( 101 formalName = "Purpose", 102 description = "A summary of the technological or business purpose of the component.", 103 useName = "purpose", 104 typeAdapter = MarkupLineAdapter.class 105 ) 106 private MarkupLine _purpose; 107 108 @BoundAssembly( 109 formalName = "Property", 110 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 111 useName = "prop", 112 maxOccurs = -1, 113 groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST) 114 ) 115 private List<Property> _props; 116 117 @BoundAssembly( 118 formalName = "Link", 119 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 120 useName = "link", 121 maxOccurs = -1, 122 groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST) 123 ) 124 private List<Link> _links; 125 126 @BoundAssembly( 127 formalName = "Responsible Role", 128 description = "A reference to a role with responsibility for performing a function relative to the containing object, optionally associated with a set of persons and/or organizations that perform that role.", 129 useName = "responsible-role", 130 maxOccurs = -1, 131 groupAs = @GroupAs(name = "responsible-roles", inJson = JsonGroupAsBehavior.LIST) 132 ) 133 private List<ResponsibleRole> _responsibleRoles; 134 135 @BoundAssembly( 136 formalName = "Service Protocol Information", 137 description = "Information about the protocol used to provide a service.", 138 useName = "protocol", 139 remarks = "Used for `service` components to define the protocols supported by the service.", 140 maxOccurs = -1, 141 groupAs = @GroupAs(name = "protocols", inJson = JsonGroupAsBehavior.LIST) 142 ) 143 private List<Protocol> _protocols; 144 145 @BoundAssembly( 146 formalName = "Control Implementation Set", 147 description = "Defines how the component or capability supports a set of controls.", 148 useName = "control-implementation", 149 maxOccurs = -1, 150 groupAs = @GroupAs(name = "control-implementations", inJson = JsonGroupAsBehavior.LIST) 151 ) 152 private List<ComponentControlImplementation> _controlImplementations; 153 154 @BoundField( 155 formalName = "Remarks", 156 description = "Additional commentary about the containing object.", 157 useName = "remarks", 158 typeAdapter = MarkupMultilineAdapter.class 159 ) 160 private MarkupMultiline _remarks; 161 162 public DefinedComponent() { 163 this(null); 164 } 165 166 public DefinedComponent(IMetaschemaData data) { 167 this.__metaschemaData = data; 168 } 169 170 @Override 171 public IMetaschemaData getMetaschemaData() { 172 return __metaschemaData; 173 } 174 175 public UUID getUuid() { 176 return _uuid; 177 } 178 179 public void setUuid(UUID value) { 180 _uuid = value; 181 } 182 183 public String getType() { 184 return _type; 185 } 186 187 public void setType(String value) { 188 _type = value; 189 } 190 191 public MarkupLine getTitle() { 192 return _title; 193 } 194 195 public void setTitle(MarkupLine value) { 196 _title = value; 197 } 198 199 public MarkupMultiline getDescription() { 200 return _description; 201 } 202 203 public void setDescription(MarkupMultiline value) { 204 _description = value; 205 } 206 207 public MarkupLine getPurpose() { 208 return _purpose; 209 } 210 211 public void setPurpose(MarkupLine value) { 212 _purpose = value; 213 } 214 215 public List<Property> getProps() { 216 return _props; 217 } 218 219 public void setProps(List<Property> value) { 220 _props = value; 221 } 222 223 /** 224 * Add a new {@link Property} item to the underlying collection. 225 * @param item the item to add 226 * @return {@code true} 227 */ 228 public boolean addProp(Property item) { 229 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 230 if (_props == null) { 231 _props = new LinkedList<>(); 232 } 233 return _props.add(value); 234 } 235 236 /** 237 * Remove the first matching {@link Property} item from the underlying collection. 238 * @param item the item to remove 239 * @return {@code true} if the item was removed or {@code false} otherwise 240 */ 241 public boolean removeProp(Property item) { 242 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 243 return _props != null && _props.remove(value); 244 } 245 246 public List<Link> getLinks() { 247 return _links; 248 } 249 250 public void setLinks(List<Link> value) { 251 _links = value; 252 } 253 254 /** 255 * Add a new {@link Link} item to the underlying collection. 256 * @param item the item to add 257 * @return {@code true} 258 */ 259 public boolean addLink(Link item) { 260 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 261 if (_links == null) { 262 _links = new LinkedList<>(); 263 } 264 return _links.add(value); 265 } 266 267 /** 268 * Remove the first matching {@link Link} item from the underlying collection. 269 * @param item the item to remove 270 * @return {@code true} if the item was removed or {@code false} otherwise 271 */ 272 public boolean removeLink(Link item) { 273 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 274 return _links != null && _links.remove(value); 275 } 276 277 public List<ResponsibleRole> getResponsibleRoles() { 278 return _responsibleRoles; 279 } 280 281 public void setResponsibleRoles(List<ResponsibleRole> value) { 282 _responsibleRoles = value; 283 } 284 285 /** 286 * Add a new {@link ResponsibleRole} item to the underlying collection. 287 * @param item the item to add 288 * @return {@code true} 289 */ 290 public boolean addResponsibleRole(ResponsibleRole item) { 291 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 292 if (_responsibleRoles == null) { 293 _responsibleRoles = new LinkedList<>(); 294 } 295 return _responsibleRoles.add(value); 296 } 297 298 /** 299 * Remove the first matching {@link ResponsibleRole} item from the underlying collection. 300 * @param item the item to remove 301 * @return {@code true} if the item was removed or {@code false} otherwise 302 */ 303 public boolean removeResponsibleRole(ResponsibleRole item) { 304 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 305 return _responsibleRoles != null && _responsibleRoles.remove(value); 306 } 307 308 public List<Protocol> getProtocols() { 309 return _protocols; 310 } 311 312 public void setProtocols(List<Protocol> value) { 313 _protocols = value; 314 } 315 316 /** 317 * Add a new {@link Protocol} item to the underlying collection. 318 * @param item the item to add 319 * @return {@code true} 320 */ 321 public boolean addProtocol(Protocol item) { 322 Protocol value = ObjectUtils.requireNonNull(item,"item cannot be null"); 323 if (_protocols == null) { 324 _protocols = new LinkedList<>(); 325 } 326 return _protocols.add(value); 327 } 328 329 /** 330 * Remove the first matching {@link Protocol} item from the underlying collection. 331 * @param item the item to remove 332 * @return {@code true} if the item was removed or {@code false} otherwise 333 */ 334 public boolean removeProtocol(Protocol item) { 335 Protocol value = ObjectUtils.requireNonNull(item,"item cannot be null"); 336 return _protocols != null && _protocols.remove(value); 337 } 338 339 public List<ComponentControlImplementation> getControlImplementations() { 340 return _controlImplementations; 341 } 342 343 public void setControlImplementations(List<ComponentControlImplementation> value) { 344 _controlImplementations = value; 345 } 346 347 /** 348 * Add a new {@link ComponentControlImplementation} item to the underlying collection. 349 * @param item the item to add 350 * @return {@code true} 351 */ 352 public boolean addControlImplementation(ComponentControlImplementation item) { 353 ComponentControlImplementation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 354 if (_controlImplementations == null) { 355 _controlImplementations = new LinkedList<>(); 356 } 357 return _controlImplementations.add(value); 358 } 359 360 /** 361 * Remove the first matching {@link ComponentControlImplementation} item from the underlying collection. 362 * @param item the item to remove 363 * @return {@code true} if the item was removed or {@code false} otherwise 364 */ 365 public boolean removeControlImplementation(ComponentControlImplementation item) { 366 ComponentControlImplementation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 367 return _controlImplementations != null && _controlImplementations.remove(value); 368 } 369 370 public MarkupMultiline getRemarks() { 371 return _remarks; 372 } 373 374 public void setRemarks(MarkupMultiline value) { 375 _remarks = value; 376 } 377 378 @Override 379 public String toString() { 380 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 381 } 382}