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.Expect; 022import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; 023import gov.nist.secauto.metaschema.databind.model.annotations.IndexHasKey; 024import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique; 025import gov.nist.secauto.metaschema.databind.model.annotations.KeyField; 026import gov.nist.secauto.metaschema.databind.model.annotations.Matches; 027import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 028import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints; 029import java.lang.Override; 030import java.lang.String; 031import java.util.LinkedList; 032import java.util.List; 033import java.util.UUID; 034import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 035import org.apache.commons.lang3.builder.ToStringStyle; 036 037/** 038 * A defined component that can be part of an implemented system. 039 */ 040@MetaschemaAssembly( 041 formalName = "Component", 042 description = "A defined component that can be part of an implemented system.", 043 name = "defined-component", 044 moduleClass = OscalComponentDefinitionModule.class, 045 remarks = "Components may be products, services, APIs, policies, processes, plans, guidance, standards, or other tangible items that enable security and/or privacy.\n" 046 + "\n" 047 + "The `type` indicates which of these component types is represented.\n" 048 + "\n" 049 + "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" 050 + "\n" 051 + "Capabilities are expressed by combining one or more components.", 052 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)}, expect = @Expect(level = IConstraint.Level.ERROR, test = "not(exists((.)[not(@type='service')]/protocol))")), 053 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.")) 054) 055public class DefinedComponent implements IBoundObject { 056 private final IMetaschemaData __metaschemaData; 057 058 /** 059 * "Provides a globally unique means to identify a given component." 060 */ 061 @BoundFlag( 062 formalName = "Component Identifier", 063 description = "Provides a globally unique means to identify a given component.", 064 name = "uuid", 065 required = true, 066 typeAdapter = UuidAdapter.class 067 ) 068 private UUID _uuid; 069 070 /** 071 * "A category describing the purpose of the component." 072 */ 073 @BoundFlag( 074 formalName = "Component Type", 075 description = "A category describing the purpose of the component.", 076 name = "type", 077 required = true, 078 typeAdapter = StringAdapter.class, 079 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.")})) 080 ) 081 private String _type; 082 083 @BoundField( 084 formalName = "Component Title", 085 description = "A human readable name for the component.", 086 useName = "title", 087 minOccurs = 1, 088 typeAdapter = MarkupLineAdapter.class 089 ) 090 private MarkupLine _title; 091 092 @BoundField( 093 formalName = "Component Description", 094 description = "A description of the component, including information about its function.", 095 useName = "description", 096 minOccurs = 1, 097 typeAdapter = MarkupMultilineAdapter.class 098 ) 099 private MarkupMultiline _description; 100 101 @BoundField( 102 formalName = "Purpose", 103 description = "A summary of the technological or business purpose of the component.", 104 useName = "purpose", 105 typeAdapter = MarkupLineAdapter.class 106 ) 107 private MarkupLine _purpose; 108 109 @BoundAssembly( 110 formalName = "Property", 111 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 112 useName = "prop", 113 maxOccurs = -1, 114 groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST) 115 ) 116 private List<Property> _props; 117 118 @BoundAssembly( 119 formalName = "Link", 120 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 121 useName = "link", 122 maxOccurs = -1, 123 groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST) 124 ) 125 private List<Link> _links; 126 127 @BoundAssembly( 128 formalName = "Responsible Role", 129 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.", 130 useName = "responsible-role", 131 maxOccurs = -1, 132 groupAs = @GroupAs(name = "responsible-roles", inJson = JsonGroupAsBehavior.LIST) 133 ) 134 private List<ResponsibleRole> _responsibleRoles; 135 136 @BoundAssembly( 137 formalName = "Service Protocol Information", 138 description = "Information about the protocol used to provide a service.", 139 useName = "protocol", 140 remarks = "Used for `service` components to define the protocols supported by the service.", 141 maxOccurs = -1, 142 groupAs = @GroupAs(name = "protocols", inJson = JsonGroupAsBehavior.LIST) 143 ) 144 private List<Protocol> _protocols; 145 146 @BoundAssembly( 147 formalName = "Control Implementation Set", 148 description = "Defines how the component or capability supports a set of controls.", 149 useName = "control-implementation", 150 maxOccurs = -1, 151 groupAs = @GroupAs(name = "control-implementations", inJson = JsonGroupAsBehavior.LIST) 152 ) 153 private List<ComponentControlImplementation> _controlImplementations; 154 155 @BoundField( 156 formalName = "Remarks", 157 description = "Additional commentary about the containing object.", 158 useName = "remarks", 159 typeAdapter = MarkupMultilineAdapter.class 160 ) 161 private MarkupMultiline _remarks; 162 163 public DefinedComponent() { 164 this(null); 165 } 166 167 public DefinedComponent(IMetaschemaData data) { 168 this.__metaschemaData = data; 169 } 170 171 @Override 172 public IMetaschemaData getMetaschemaData() { 173 return __metaschemaData; 174 } 175 176 public UUID getUuid() { 177 return _uuid; 178 } 179 180 public void setUuid(UUID value) { 181 _uuid = value; 182 } 183 184 public String getType() { 185 return _type; 186 } 187 188 public void setType(String value) { 189 _type = value; 190 } 191 192 public MarkupLine getTitle() { 193 return _title; 194 } 195 196 public void setTitle(MarkupLine value) { 197 _title = value; 198 } 199 200 public MarkupMultiline getDescription() { 201 return _description; 202 } 203 204 public void setDescription(MarkupMultiline value) { 205 _description = value; 206 } 207 208 public MarkupLine getPurpose() { 209 return _purpose; 210 } 211 212 public void setPurpose(MarkupLine value) { 213 _purpose = value; 214 } 215 216 public List<Property> getProps() { 217 return _props; 218 } 219 220 public void setProps(List<Property> value) { 221 _props = value; 222 } 223 224 /** 225 * Add a new {@link Property} item to the underlying collection. 226 * @param item the item to add 227 * @return {@code true} 228 */ 229 public boolean addProp(Property item) { 230 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 231 if (_props == null) { 232 _props = new LinkedList<>(); 233 } 234 return _props.add(value); 235 } 236 237 /** 238 * Remove the first matching {@link Property} item from the underlying collection. 239 * @param item the item to remove 240 * @return {@code true} if the item was removed or {@code false} otherwise 241 */ 242 public boolean removeProp(Property item) { 243 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 244 return _props != null && _props.remove(value); 245 } 246 247 public List<Link> getLinks() { 248 return _links; 249 } 250 251 public void setLinks(List<Link> value) { 252 _links = value; 253 } 254 255 /** 256 * Add a new {@link Link} item to the underlying collection. 257 * @param item the item to add 258 * @return {@code true} 259 */ 260 public boolean addLink(Link item) { 261 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 262 if (_links == null) { 263 _links = new LinkedList<>(); 264 } 265 return _links.add(value); 266 } 267 268 /** 269 * Remove the first matching {@link Link} item from the underlying collection. 270 * @param item the item to remove 271 * @return {@code true} if the item was removed or {@code false} otherwise 272 */ 273 public boolean removeLink(Link item) { 274 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 275 return _links != null && _links.remove(value); 276 } 277 278 public List<ResponsibleRole> getResponsibleRoles() { 279 return _responsibleRoles; 280 } 281 282 public void setResponsibleRoles(List<ResponsibleRole> value) { 283 _responsibleRoles = value; 284 } 285 286 /** 287 * Add a new {@link ResponsibleRole} item to the underlying collection. 288 * @param item the item to add 289 * @return {@code true} 290 */ 291 public boolean addResponsibleRole(ResponsibleRole item) { 292 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 293 if (_responsibleRoles == null) { 294 _responsibleRoles = new LinkedList<>(); 295 } 296 return _responsibleRoles.add(value); 297 } 298 299 /** 300 * Remove the first matching {@link ResponsibleRole} item from the underlying collection. 301 * @param item the item to remove 302 * @return {@code true} if the item was removed or {@code false} otherwise 303 */ 304 public boolean removeResponsibleRole(ResponsibleRole item) { 305 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 306 return _responsibleRoles != null && _responsibleRoles.remove(value); 307 } 308 309 public List<Protocol> getProtocols() { 310 return _protocols; 311 } 312 313 public void setProtocols(List<Protocol> value) { 314 _protocols = value; 315 } 316 317 /** 318 * Add a new {@link Protocol} item to the underlying collection. 319 * @param item the item to add 320 * @return {@code true} 321 */ 322 public boolean addProtocol(Protocol item) { 323 Protocol value = ObjectUtils.requireNonNull(item,"item cannot be null"); 324 if (_protocols == null) { 325 _protocols = new LinkedList<>(); 326 } 327 return _protocols.add(value); 328 } 329 330 /** 331 * Remove the first matching {@link Protocol} item from the underlying collection. 332 * @param item the item to remove 333 * @return {@code true} if the item was removed or {@code false} otherwise 334 */ 335 public boolean removeProtocol(Protocol item) { 336 Protocol value = ObjectUtils.requireNonNull(item,"item cannot be null"); 337 return _protocols != null && _protocols.remove(value); 338 } 339 340 public List<ComponentControlImplementation> getControlImplementations() { 341 return _controlImplementations; 342 } 343 344 public void setControlImplementations(List<ComponentControlImplementation> value) { 345 _controlImplementations = value; 346 } 347 348 /** 349 * Add a new {@link ComponentControlImplementation} item to the underlying collection. 350 * @param item the item to add 351 * @return {@code true} 352 */ 353 public boolean addControlImplementation(ComponentControlImplementation item) { 354 ComponentControlImplementation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 355 if (_controlImplementations == null) { 356 _controlImplementations = new LinkedList<>(); 357 } 358 return _controlImplementations.add(value); 359 } 360 361 /** 362 * Remove the first matching {@link ComponentControlImplementation} item from the underlying collection. 363 * @param item the item to remove 364 * @return {@code true} if the item was removed or {@code false} otherwise 365 */ 366 public boolean removeControlImplementation(ComponentControlImplementation item) { 367 ComponentControlImplementation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 368 return _controlImplementations != null && _controlImplementations.remove(value); 369 } 370 371 public MarkupMultiline getRemarks() { 372 return _remarks; 373 } 374 375 public void setRemarks(MarkupMultiline value) { 376 _remarks = value; 377 } 378 379 @Override 380 public String toString() { 381 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 382 } 383}