001package gov.nist.secauto.oscal.lib.model;
002
003import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter;
004import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
005import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultilineAdapter;
006import gov.nist.secauto.metaschema.core.model.IBoundObject;
007import gov.nist.secauto.metaschema.core.model.IMetaschemaData;
008import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior;
009import gov.nist.secauto.metaschema.core.model.constraint.IConstraint;
010import gov.nist.secauto.metaschema.core.util.ObjectUtils;
011import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints;
012import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly;
013import gov.nist.secauto.metaschema.databind.model.annotations.BoundField;
014import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
015import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs;
016import gov.nist.secauto.metaschema.databind.model.annotations.Index;
017import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique;
018import gov.nist.secauto.metaschema.databind.model.annotations.KeyField;
019import gov.nist.secauto.metaschema.databind.model.annotations.Let;
020import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
021import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
022import java.lang.Override;
023import java.lang.String;
024import java.util.LinkedList;
025import java.util.List;
026import java.util.UUID;
027import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
028import org.apache.commons.lang3.builder.ToStringStyle;
029
030/**
031 * Security assessment results, such as those provided by a FedRAMP assessor in the FedRAMP Security Assessment Report.
032 */
033@MetaschemaAssembly(
034    formalName = "Security Assessment Results (SAR)",
035    description = "Security assessment results, such as those provided by a FedRAMP assessor in the FedRAMP Security Assessment Report.",
036    name = "assessment-results",
037    moduleClass = OscalArModule.class,
038    rootName = "assessment-results",
039    valueConstraints = @ValueConstraints(lets = @Let(name = "all-imports", target = "recurse-depth('.[import-ap]/doc(resolve-uri(Q{http://csrc.nist.gov/ns/oscal/1.0}resolve-reference(import-ap/@href)))/assessment-plan|.[import-ssp]/doc(resolve-uri(Q{http://csrc.nist.gov/ns/oscal/1.0}resolve-reference(import-ssp/@href)))/system-security-plan|.[import-profile]/resolve-profile(doc(resolve-uri(Q{http://csrc.nist.gov/ns/oscal/1.0}resolve-reference(import-profile/@href))))/catalog')")),
040    modelConstraints = @AssemblyConstraints(index = {@Index(id = "oscal-ar-index-metadata-scoped-role-id", formalName = "In-Scope Role Identifiers", description = "An index of role identifiers that are in-scope for the assessment-result model. Roles are collected from imported assessment-plans, which in turn includes referenced system-securtity-plans, which in turn includes referenced profiles and catalogs. For a given role @id, a locally declared role takes precedence over a role that is imported, the role that was last imported.", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/role ! map:entry(@id,.))?*", name = "index-imports-metadata-role-id", keyFields = @KeyField(target = "@id")), @Index(id = "oscal-ar-index-metadata-scoped-location-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/location ! map:entry(@uuid,.))?*", name = "index-imports-metadata-location-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-ar-index-metadata-scoped-party-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/party ! map:entry(@uuid,.))?*", name = "index-imports-metadata-party-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-ar-index-metadata-scoped-party-organization-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/party[@type='organization'] ! map:entry(@uuid,.))?*", name = "index-imports-metadata-party-organization-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-ar-index-metadata-scoped-property-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports//prop[@uuid] ! map:entry(@uuid,.))?*", name = "index-imports-metadata-property-uuid", keyFields = @KeyField(target = "@uuid"))}, unique = {@IsUnique(id = "oscal-unique-document-id", formalName = "Unique Document Identifier", description = "Ensure all document identifiers have a unique combination of @scheme and value.", level = IConstraint.Level.ERROR, target = "document-id", keyFields = {@KeyField(target = "@scheme"), @KeyField}), @IsUnique(id = "oscal-unique-property-in-context-location", formalName = "Unique Properties", description = "Ensure all properties are unique for a given location using a unique combination of @ns, @name, @class. @group. and @value.", level = IConstraint.Level.ERROR, target = ".//prop", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@name"), @KeyField(target = "@ns"), @KeyField(target = "@class"), @KeyField(target = "@group"), @KeyField(target = "@value")}), @IsUnique(id = "oscal-unique-link-in-context-location", formalName = "Unique Links", description = "Ensure all links are unique for a given location using a unique combination of @href, @rel, and @media-type.", level = IConstraint.Level.ERROR, target = ".//link", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@href"), @KeyField(target = "@rel"), @KeyField(target = "@media-type")}), @IsUnique(id = "oscal-unique-responsibility-in-context-location", formalName = "Unique Responsibilities", description = "Ensure all responsible-roles and responsible-parties are unique for a given location using a unique combination of @role-id and the combination of @party-uuid values.", level = IConstraint.Level.ERROR, target = ".//(responsible-party|responsible-role)", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@role-id"), @KeyField(target = "@party-uuid")}, remarks = "Since `responsible-party` and `responsible-role` associate multiple `party-uuid` entries with a single `role-id`, each role-id must be referenced only once.")})
041)
042public class AssessmentResults extends AbstractOscalInstance implements IBoundObject {
043  private final IMetaschemaData __metaschemaData;
044
045  /**
046   * "A <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented\">machine-oriented</a>, <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique\">globally unique</a> identifier with <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance\">cross-instance</a> scope that can be used to reference this assessment results instance in <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#ar-identifiers\">this or other OSCAL instances</a>. The locally defined <em>UUID</em> of the <code>assessment result</code> can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency\">per-subject</a>, which means it should be consistently used to identify the same subject across revisions of the document."
047   */
048  @BoundFlag(
049      formalName = "Assessment Results Universally Unique Identifier",
050      description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with [cross-instance](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this assessment results instance in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#ar-identifiers). The locally defined *UUID* of the `assessment result` can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned [per-subject](https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency), which means it should be consistently used to identify the same subject across revisions of the document.",
051      name = "uuid",
052      required = true,
053      typeAdapter = UuidAdapter.class
054  )
055  private UUID _uuid;
056
057  @BoundAssembly(
058      formalName = "Document Metadata",
059      description = "Provides information about the containing document, and defines concepts that are shared across the document.",
060      useName = "metadata",
061      minOccurs = 1
062  )
063  private Metadata _metadata;
064
065  @BoundAssembly(
066      formalName = "Import Assessment Plan",
067      description = "Used by assessment-results to import information about the original plan for assessing the system.",
068      useName = "import-ap",
069      remarks = "Used by the SAR to import information about the original plan for assessing the system.",
070      minOccurs = 1
071  )
072  private ImportAp _importAp;
073
074  @BoundAssembly(
075      formalName = "Local Definitions",
076      description = "Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.",
077      useName = "local-definitions"
078  )
079  private LocalDefinitions _localDefinitions;
080
081  @BoundAssembly(
082      formalName = "Assessment Result",
083      description = "Used by the assessment results and POA\\&M. In the assessment results, this identifies all of the assessment observations and findings, initial and residual risks, deviations, and disposition. In the POA\\&M, this identifies initial and residual risks, deviations, and disposition.",
084      useName = "result",
085      minOccurs = 1,
086      maxOccurs = -1,
087      groupAs = @GroupAs(name = "results", inJson = JsonGroupAsBehavior.LIST)
088  )
089  private List<Result> _results;
090
091  @BoundAssembly(
092      formalName = "Back matter",
093      description = "A collection of resources that may be referenced from within the OSCAL document instance.",
094      useName = "back-matter"
095  )
096  private BackMatter _backMatter;
097
098  public AssessmentResults() {
099    this(null);
100  }
101
102  public AssessmentResults(IMetaschemaData data) {
103    this.__metaschemaData = data;
104  }
105
106  @Override
107  public IMetaschemaData getMetaschemaData() {
108    return __metaschemaData;
109  }
110
111  public UUID getUuid() {
112    return _uuid;
113  }
114
115  public void setUuid(UUID value) {
116    _uuid = value;
117  }
118
119  public Metadata getMetadata() {
120    return _metadata;
121  }
122
123  public void setMetadata(Metadata value) {
124    _metadata = value;
125  }
126
127  public ImportAp getImportAp() {
128    return _importAp;
129  }
130
131  public void setImportAp(ImportAp value) {
132    _importAp = value;
133  }
134
135  public LocalDefinitions getLocalDefinitions() {
136    return _localDefinitions;
137  }
138
139  public void setLocalDefinitions(LocalDefinitions value) {
140    _localDefinitions = value;
141  }
142
143  public List<Result> getResults() {
144    return _results;
145  }
146
147  public void setResults(List<Result> value) {
148    _results = value;
149  }
150
151  /**
152   * Add a new {@link Result} item to the underlying collection.
153   * @param item the item to add
154   * @return {@code true}
155   */
156  public boolean addResult(Result item) {
157    Result value = ObjectUtils.requireNonNull(item,"item cannot be null");
158    if (_results == null) {
159      _results = new LinkedList<>();
160    }
161    return _results.add(value);
162  }
163
164  /**
165   * Remove the first matching {@link Result} item from the underlying collection.
166   * @param item the item to remove
167   * @return {@code true} if the item was removed or {@code false} otherwise
168   */
169  public boolean removeResult(Result item) {
170    Result value = ObjectUtils.requireNonNull(item,"item cannot be null");
171    return _results != null && _results.remove(value);
172  }
173
174  public BackMatter getBackMatter() {
175    return _backMatter;
176  }
177
178  public void setBackMatter(BackMatter value) {
179    _backMatter = value;
180  }
181
182  @Override
183  public String toString() {
184    return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString();
185  }
186
187  /**
188   * Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.
189   */
190  @MetaschemaAssembly(
191      formalName = "Local Definitions",
192      description = "Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.",
193      name = "local-definitions",
194      moduleClass = OscalArModule.class
195  )
196  public static class LocalDefinitions implements IBoundObject {
197    private final IMetaschemaData __metaschemaData;
198
199    @BoundAssembly(
200        formalName = "Assessment-Specific Control Objective",
201        description = "A local definition of a control objective for this assessment. Uses catalog syntax for control objective and assessment actions.",
202        useName = "objectives-and-methods",
203        maxOccurs = -1,
204        groupAs = @GroupAs(name = "objectives-and-methods", inJson = JsonGroupAsBehavior.LIST)
205    )
206    private List<LocalObjective> _objectivesAndMethods;
207
208    @BoundAssembly(
209        formalName = "Activity",
210        description = "Identifies an assessment or related process that can be performed. In the assessment plan, this is an intended activity which may be associated with an assessment task. In the assessment results, this an activity that was actually performed as part of an assessment.",
211        useName = "activity",
212        maxOccurs = -1,
213        groupAs = @GroupAs(name = "activities", inJson = JsonGroupAsBehavior.LIST)
214    )
215    private List<Activity> _activities;
216
217    @BoundField(
218        formalName = "Remarks",
219        description = "Additional commentary about the containing object.",
220        useName = "remarks",
221        typeAdapter = MarkupMultilineAdapter.class
222    )
223    private MarkupMultiline _remarks;
224
225    public LocalDefinitions() {
226      this(null);
227    }
228
229    public LocalDefinitions(IMetaschemaData data) {
230      this.__metaschemaData = data;
231    }
232
233    @Override
234    public IMetaschemaData getMetaschemaData() {
235      return __metaschemaData;
236    }
237
238    public List<LocalObjective> getObjectivesAndMethods() {
239      return _objectivesAndMethods;
240    }
241
242    public void setObjectivesAndMethods(List<LocalObjective> value) {
243      _objectivesAndMethods = value;
244    }
245
246    /**
247     * Add a new {@link LocalObjective} item to the underlying collection.
248     * @param item the item to add
249     * @return {@code true}
250     */
251    public boolean addObjectivesAndMethods(LocalObjective item) {
252      LocalObjective value = ObjectUtils.requireNonNull(item,"item cannot be null");
253      if (_objectivesAndMethods == null) {
254        _objectivesAndMethods = new LinkedList<>();
255      }
256      return _objectivesAndMethods.add(value);
257    }
258
259    /**
260     * Remove the first matching {@link LocalObjective} item from the underlying collection.
261     * @param item the item to remove
262     * @return {@code true} if the item was removed or {@code false} otherwise
263     */
264    public boolean removeObjectivesAndMethods(LocalObjective item) {
265      LocalObjective value = ObjectUtils.requireNonNull(item,"item cannot be null");
266      return _objectivesAndMethods != null && _objectivesAndMethods.remove(value);
267    }
268
269    public List<Activity> getActivities() {
270      return _activities;
271    }
272
273    public void setActivities(List<Activity> value) {
274      _activities = value;
275    }
276
277    /**
278     * Add a new {@link Activity} item to the underlying collection.
279     * @param item the item to add
280     * @return {@code true}
281     */
282    public boolean addActivity(Activity item) {
283      Activity value = ObjectUtils.requireNonNull(item,"item cannot be null");
284      if (_activities == null) {
285        _activities = new LinkedList<>();
286      }
287      return _activities.add(value);
288    }
289
290    /**
291     * Remove the first matching {@link Activity} item from the underlying collection.
292     * @param item the item to remove
293     * @return {@code true} if the item was removed or {@code false} otherwise
294     */
295    public boolean removeActivity(Activity item) {
296      Activity value = ObjectUtils.requireNonNull(item,"item cannot be null");
297      return _activities != null && _activities.remove(value);
298    }
299
300    public MarkupMultiline getRemarks() {
301      return _remarks;
302    }
303
304    public void setRemarks(MarkupMultiline value) {
305      _remarks = value;
306    }
307
308    @Override
309    public String toString() {
310      return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString();
311    }
312  }
313}