001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue; 004import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues; 005import gov.nist.secauto.metaschema.binding.model.annotations.AssemblyConstraints; 006import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly; 007import gov.nist.secauto.metaschema.binding.model.annotations.BoundField; 008import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue; 009import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag; 010import gov.nist.secauto.metaschema.binding.model.annotations.Expect; 011import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs; 012import gov.nist.secauto.metaschema.binding.model.annotations.IndexHasKey; 013import gov.nist.secauto.metaschema.binding.model.annotations.IsUnique; 014import gov.nist.secauto.metaschema.binding.model.annotations.KeyField; 015import gov.nist.secauto.metaschema.binding.model.annotations.Matches; 016import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly; 017import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints; 018import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior; 019import gov.nist.secauto.metaschema.model.common.constraint.IConstraint; 020import gov.nist.secauto.metaschema.model.common.datatype.adapter.DateAdapter; 021import gov.nist.secauto.metaschema.model.common.datatype.adapter.StringAdapter; 022import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter; 023import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine; 024import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter; 025import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline; 026import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter; 027import gov.nist.secauto.metaschema.model.common.util.ObjectUtils; 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.MultilineRecursiveToStringStyle; 034import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 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 metaschema = OscalComponentDefinitionMetaschema.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) 052@ValueConstraints( 053 allowedValues = { 054 @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.")}), 055 @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.")}), 056 @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).")}), 057 @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.")}), 058 @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.")}), 059 @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.")}), 060 @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.")}), 061 @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.")}), 062 @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.")), 063 @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.")}) 064 }, 065 indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, target = "prop[@name='physical-location']", indexName = "index-metadata-location-uuid", keyFields = @KeyField(target = "@value")), 066 matches = { 067 @Matches(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='inherited-uuid']/@value", typeAdapter = UuidAdapter.class), 068 @Matches(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='release-date']/@value", typeAdapter = DateAdapter.class) 069 }, 070 expect = @Expect(level = IConstraint.Level.ERROR, test = "not(exists((.)[not(@type='service')]/protocol))") 071) 072@AssemblyConstraints( 073 isUnique = @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.") 074) 075public class DefinedComponent { 076 @BoundFlag( 077 formalName = "Component Identifier", 078 description = "Provides a globally unique means to identify a given component.", 079 useName = "uuid", 080 required = true, 081 typeAdapter = UuidAdapter.class 082 ) 083 private UUID _uuid; 084 085 @BoundFlag( 086 formalName = "Component Type", 087 description = "A category describing the purpose of the component.", 088 useName = "type", 089 required = true, 090 typeAdapter = StringAdapter.class 091 ) 092 @ValueConstraints( 093 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.")}) 094 ) 095 private String _type; 096 097 /** 098 * "A human readable name for the component." 099 */ 100 @BoundField( 101 formalName = "Component Title", 102 description = "A human readable name for the component.", 103 useName = "title", 104 minOccurs = 1 105 ) 106 @BoundFieldValue( 107 typeAdapter = MarkupLineAdapter.class 108 ) 109 private MarkupLine _title; 110 111 /** 112 * "A description of the component, including information about its function." 113 */ 114 @BoundField( 115 formalName = "Component Description", 116 description = "A description of the component, including information about its function.", 117 useName = "description", 118 minOccurs = 1 119 ) 120 @BoundFieldValue( 121 typeAdapter = MarkupMultilineAdapter.class 122 ) 123 private MarkupMultiline _description; 124 125 /** 126 * "A summary of the technological or business purpose of the component." 127 */ 128 @BoundField( 129 formalName = "Purpose", 130 description = "A summary of the technological or business purpose of the component.", 131 useName = "purpose" 132 ) 133 @BoundFieldValue( 134 typeAdapter = MarkupLineAdapter.class 135 ) 136 private MarkupLine _purpose; 137 138 @BoundAssembly( 139 formalName = "Property", 140 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 141 useName = "prop", 142 maxOccurs = -1 143 ) 144 @GroupAs( 145 name = "props", 146 inJson = JsonGroupAsBehavior.LIST 147 ) 148 private List<Property> _props; 149 150 @BoundAssembly( 151 formalName = "Link", 152 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 153 useName = "link", 154 maxOccurs = -1 155 ) 156 @GroupAs( 157 name = "links", 158 inJson = JsonGroupAsBehavior.LIST 159 ) 160 private List<Link> _links; 161 162 @BoundAssembly( 163 formalName = "Responsible Role", 164 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.", 165 useName = "responsible-role", 166 maxOccurs = -1 167 ) 168 @GroupAs( 169 name = "responsible-roles", 170 inJson = JsonGroupAsBehavior.LIST 171 ) 172 private List<ResponsibleRole> _responsibleRoles; 173 174 @BoundAssembly( 175 formalName = "Service Protocol Information", 176 description = "Information about the protocol used to provide a service.", 177 useName = "protocol", 178 maxOccurs = -1, 179 remarks = "Used for `service` components to define the protocols supported by the service." 180 ) 181 @GroupAs( 182 name = "protocols", 183 inJson = JsonGroupAsBehavior.LIST 184 ) 185 private List<Protocol> _protocols; 186 187 @BoundAssembly( 188 formalName = "Control Implementation Set", 189 description = "Defines how the component or capability supports a set of controls.", 190 useName = "control-implementation", 191 maxOccurs = -1 192 ) 193 @GroupAs( 194 name = "control-implementations", 195 inJson = JsonGroupAsBehavior.LIST 196 ) 197 private List<ComponentControlImplementation> _controlImplementations; 198 199 @BoundField( 200 formalName = "Remarks", 201 description = "Additional commentary about the containing object.", 202 useName = "remarks" 203 ) 204 @BoundFieldValue( 205 typeAdapter = MarkupMultilineAdapter.class 206 ) 207 private MarkupMultiline _remarks; 208 209 public DefinedComponent() { 210 } 211 212 public UUID getUuid() { 213 return _uuid; 214 } 215 216 public void setUuid(UUID value) { 217 _uuid = value; 218 } 219 220 public String getType() { 221 return _type; 222 } 223 224 public void setType(String value) { 225 _type = value; 226 } 227 228 public MarkupLine getTitle() { 229 return _title; 230 } 231 232 public void setTitle(MarkupLine value) { 233 _title = value; 234 } 235 236 public MarkupMultiline getDescription() { 237 return _description; 238 } 239 240 public void setDescription(MarkupMultiline value) { 241 _description = value; 242 } 243 244 public MarkupLine getPurpose() { 245 return _purpose; 246 } 247 248 public void setPurpose(MarkupLine value) { 249 _purpose = value; 250 } 251 252 public List<Property> getProps() { 253 return _props; 254 } 255 256 public void setProps(List<Property> value) { 257 _props = value; 258 } 259 260 /** 261 * Add a new {@link Property} item to the underlying collection. 262 * @param item the item to add 263 * @return {@code true} 264 */ 265 public boolean addProp(Property item) { 266 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 267 if (_props == null) { 268 _props = new LinkedList<>(); 269 } 270 return _props.add(value); 271 } 272 273 /** 274 * Remove the first matching {@link Property} item from the underlying collection. 275 * @param item the item to remove 276 * @return {@code true} if the item was removed or {@code false} otherwise 277 */ 278 public boolean removeProp(Property item) { 279 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 280 return _props == null ? false : _props.remove(value); 281 } 282 283 public List<Link> getLinks() { 284 return _links; 285 } 286 287 public void setLinks(List<Link> value) { 288 _links = value; 289 } 290 291 /** 292 * Add a new {@link Link} item to the underlying collection. 293 * @param item the item to add 294 * @return {@code true} 295 */ 296 public boolean addLink(Link item) { 297 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 298 if (_links == null) { 299 _links = new LinkedList<>(); 300 } 301 return _links.add(value); 302 } 303 304 /** 305 * Remove the first matching {@link Link} item from the underlying collection. 306 * @param item the item to remove 307 * @return {@code true} if the item was removed or {@code false} otherwise 308 */ 309 public boolean removeLink(Link item) { 310 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 311 return _links == null ? false : _links.remove(value); 312 } 313 314 public List<ResponsibleRole> getResponsibleRoles() { 315 return _responsibleRoles; 316 } 317 318 public void setResponsibleRoles(List<ResponsibleRole> value) { 319 _responsibleRoles = value; 320 } 321 322 /** 323 * Add a new {@link ResponsibleRole} item to the underlying collection. 324 * @param item the item to add 325 * @return {@code true} 326 */ 327 public boolean addResponsibleRole(ResponsibleRole item) { 328 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 329 if (_responsibleRoles == null) { 330 _responsibleRoles = new LinkedList<>(); 331 } 332 return _responsibleRoles.add(value); 333 } 334 335 /** 336 * Remove the first matching {@link ResponsibleRole} item from the underlying collection. 337 * @param item the item to remove 338 * @return {@code true} if the item was removed or {@code false} otherwise 339 */ 340 public boolean removeResponsibleRole(ResponsibleRole item) { 341 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 342 return _responsibleRoles == null ? false : _responsibleRoles.remove(value); 343 } 344 345 public List<Protocol> getProtocols() { 346 return _protocols; 347 } 348 349 public void setProtocols(List<Protocol> value) { 350 _protocols = value; 351 } 352 353 /** 354 * Add a new {@link Protocol} item to the underlying collection. 355 * @param item the item to add 356 * @return {@code true} 357 */ 358 public boolean addProtocol(Protocol item) { 359 Protocol value = ObjectUtils.requireNonNull(item,"item cannot be null"); 360 if (_protocols == null) { 361 _protocols = new LinkedList<>(); 362 } 363 return _protocols.add(value); 364 } 365 366 /** 367 * Remove the first matching {@link Protocol} item from the underlying collection. 368 * @param item the item to remove 369 * @return {@code true} if the item was removed or {@code false} otherwise 370 */ 371 public boolean removeProtocol(Protocol item) { 372 Protocol value = ObjectUtils.requireNonNull(item,"item cannot be null"); 373 return _protocols == null ? false : _protocols.remove(value); 374 } 375 376 public List<ComponentControlImplementation> getControlImplementations() { 377 return _controlImplementations; 378 } 379 380 public void setControlImplementations(List<ComponentControlImplementation> value) { 381 _controlImplementations = value; 382 } 383 384 /** 385 * Add a new {@link ComponentControlImplementation} item to the underlying collection. 386 * @param item the item to add 387 * @return {@code true} 388 */ 389 public boolean addControlImplementation(ComponentControlImplementation item) { 390 ComponentControlImplementation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 391 if (_controlImplementations == null) { 392 _controlImplementations = new LinkedList<>(); 393 } 394 return _controlImplementations.add(value); 395 } 396 397 /** 398 * Remove the first matching {@link ComponentControlImplementation} item from the underlying collection. 399 * @param item the item to remove 400 * @return {@code true} if the item was removed or {@code false} otherwise 401 */ 402 public boolean removeControlImplementation(ComponentControlImplementation item) { 403 ComponentControlImplementation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 404 return _controlImplementations == null ? false : _controlImplementations.remove(value); 405 } 406 407 public MarkupMultiline getRemarks() { 408 return _remarks; 409 } 410 411 public void setRemarks(MarkupMultiline value) { 412 _remarks = value; 413 } 414 415 @Override 416 public String toString() { 417 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 418 } 419}