|
33 | 33 |
|
34 | 34 | from .._internal.compare import ComparableTuple as _ComparableTuple
|
35 | 35 | from ..schema.schema import SchemaVersion1Dot3, SchemaVersion1Dot4, SchemaVersion1Dot5, SchemaVersion1Dot6
|
36 |
| -from . import DataClassification, ExternalReference, Property, XsUri |
| 36 | +from . import DataClassification, DataFlow, ExternalReference, Property, XsUri |
37 | 37 | from .bom_ref import BomRef
|
38 | 38 | from .contact import OrganizationalEntity
|
39 | 39 | from .dependency import Dependable
|
@@ -381,3 +381,266 @@ def __hash__(self) -> int:
|
381 | 381 |
|
382 | 382 | def __repr__(self) -> str:
|
383 | 383 | return f'<Service bom-ref={self.bom_ref}, group={self.group}, name={self.name}, version={self.version}>'
|
| 384 | + |
| 385 | + |
| 386 | +@serializable.serializable_class |
| 387 | +class OrganizationOrIndividualType: |
| 388 | + """ |
| 389 | + This is our internal representation of the organizationOrIndividualType complex type within the CycloneDX standard. |
| 390 | +
|
| 391 | + .. note:: |
| 392 | + See the CycloneDX Schema: https://cyclonedx.org/docs/1.6/xml/#type_organizationOrIndividualType |
| 393 | + """ |
| 394 | + |
| 395 | + def __init__( |
| 396 | + self, *, |
| 397 | + organization: Optional[OrganizationalEntity] = None, |
| 398 | + individual: Optional[OrganizationalEntity] = None, |
| 399 | + ) -> None: |
| 400 | + self.organization = organization |
| 401 | + self.individual = individual |
| 402 | + |
| 403 | + # Property for organization |
| 404 | + @property |
| 405 | + @serializable.xml_sequence(1) |
| 406 | + @serializable.xml_name('organization') |
| 407 | + def organization(self) -> Optional[OrganizationalEntity]: |
| 408 | + return self._organization |
| 409 | + |
| 410 | + @organization.setter |
| 411 | + def organization(self, organization: Optional[OrganizationalEntity]) -> None: |
| 412 | + self._organization = organization |
| 413 | + |
| 414 | + # Property for individual |
| 415 | + @property |
| 416 | + @serializable.xml_sequence(2) |
| 417 | + @serializable.xml_name('individual') |
| 418 | + def individual(self) -> Optional[OrganizationalEntity]: |
| 419 | + return self._individual |
| 420 | + |
| 421 | + @individual.setter |
| 422 | + def individual(self, individual: Optional[OrganizationalEntity]) -> None: |
| 423 | + self._individual = individual |
| 424 | + |
| 425 | + |
| 426 | +@serializable.serializable_class |
| 427 | +class DataGovernance: |
| 428 | + """ |
| 429 | + This is our internal representation of the dataGovernance complex type within the CycloneDX standard. |
| 430 | +
|
| 431 | + .. note:: |
| 432 | + See the CycloneDX Schema: https://cyclonedx.org/docs/1.6/xml/#type_dataGovernance |
| 433 | + """ |
| 434 | + |
| 435 | + def __init__( |
| 436 | + self, *, |
| 437 | + custodian: Optional[OrganizationOrIndividualType] = None, |
| 438 | + steward: Optional[OrganizationOrIndividualType] = None, |
| 439 | + owner: Optional[OrganizationOrIndividualType] = None, |
| 440 | + ) -> None: |
| 441 | + self.custodian = custodian |
| 442 | + self.steward = steward |
| 443 | + self.owner = owner |
| 444 | + |
| 445 | + # Property for custodian |
| 446 | + @property |
| 447 | + @serializable.xml_sequence(1) |
| 448 | + @serializable.xml_name('custodian') |
| 449 | + def custodian(self) -> Optional[OrganizationOrIndividualType]: |
| 450 | + return self._custodian |
| 451 | + |
| 452 | + @custodian.setter |
| 453 | + def custodian(self, custodian: Optional[OrganizationOrIndividualType]) -> None: |
| 454 | + self._custodian = custodian |
| 455 | + |
| 456 | + # Property for steward |
| 457 | + @property |
| 458 | + @serializable.xml_sequence(2) |
| 459 | + @serializable.xml_name('steward') |
| 460 | + def steward(self) -> Optional[OrganizationOrIndividualType]: |
| 461 | + return self._steward |
| 462 | + |
| 463 | + @steward.setter |
| 464 | + def steward(self, steward: Optional[OrganizationOrIndividualType]) -> None: |
| 465 | + self._steward = steward |
| 466 | + |
| 467 | + # Property for owner |
| 468 | + @property |
| 469 | + @serializable.xml_sequence(3) |
| 470 | + @serializable.xml_name('owner') |
| 471 | + def owner(self) -> Optional[OrganizationOrIndividualType]: |
| 472 | + return self._owner |
| 473 | + |
| 474 | + @owner.setter |
| 475 | + def owner(self, owner: Optional[OrganizationOrIndividualType]) -> None: |
| 476 | + self._owner = owner |
| 477 | + |
| 478 | + |
| 479 | +@serializable.serializable_class |
| 480 | +class Data: |
| 481 | + """ |
| 482 | + This is our internal representation of the service.data complex type within the CycloneDX standard. |
| 483 | +
|
| 484 | + .. note:: |
| 485 | + See the CycloneDX Schema: https://cyclonedx.org/docs/1.6/xml/#type_service |
| 486 | + """ |
| 487 | + # @serializable.xml_string(serializable.XmlStringSerializationType.STRING) |
| 488 | + |
| 489 | + def __init__( |
| 490 | + self, *, |
| 491 | + flow: DataFlow, |
| 492 | + classification: str, |
| 493 | + name: Optional[str] = None, |
| 494 | + description: Optional[str] = None, |
| 495 | + governance: Optional[DataGovernance] = None, |
| 496 | + source: Optional[Iterable[Union[BomRef, XsUri]]] = None, |
| 497 | + destination: Optional[Iterable[Union[BomRef, XsUri]]] = None |
| 498 | + ) -> None: |
| 499 | + self.flow = flow |
| 500 | + self.classification = classification |
| 501 | + self.name = name |
| 502 | + self.description = description |
| 503 | + self.governance = governance |
| 504 | + self.source = source |
| 505 | + self.destination = destination |
| 506 | + |
| 507 | + @property |
| 508 | + @serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING) |
| 509 | + def name(self) -> Optional[str]: |
| 510 | + """ |
| 511 | + The name of the service data. |
| 512 | +
|
| 513 | + Returns: |
| 514 | + `str` if provided else None |
| 515 | + """ |
| 516 | + return self._name |
| 517 | + |
| 518 | + @name.setter |
| 519 | + def name(self, name: Optional[str]) -> None: |
| 520 | + self._name = name |
| 521 | + |
| 522 | + @property |
| 523 | + @serializable.xml_attribute() |
| 524 | + def flow(self) -> DataFlow: |
| 525 | + """ |
| 526 | + Specifies the flow direction of the data. |
| 527 | +
|
| 528 | + Valid values are: inbound, outbound, bi-directional, and unknown. |
| 529 | +
|
| 530 | + Direction is relative to the service. |
| 531 | +
|
| 532 | + - Inbound flow states that data enters the service |
| 533 | + - Outbound flow states that data leaves the service |
| 534 | + - Bi-directional states that data flows both ways |
| 535 | + - Unknown states that the direction is not known |
| 536 | +
|
| 537 | + Returns: |
| 538 | + `DataFlow` |
| 539 | + """ |
| 540 | + return self._flow |
| 541 | + |
| 542 | + @flow.setter |
| 543 | + def flow(self, flow: DataFlow) -> None: |
| 544 | + self._flow = flow |
| 545 | + |
| 546 | + @property |
| 547 | + @serializable.xml_name('.') |
| 548 | + @serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING) |
| 549 | + def classification(self) -> str: |
| 550 | + """ |
| 551 | + Data classification tags data according to its type, sensitivity, and value if altered, stolen, or destroyed. |
| 552 | +
|
| 553 | + Returns: |
| 554 | + `str` |
| 555 | + """ |
| 556 | + return self._classification |
| 557 | + |
| 558 | + @classification.setter |
| 559 | + def classification(self, classification: str) -> None: |
| 560 | + self._classification = classification |
| 561 | + |
| 562 | + # description property |
| 563 | + |
| 564 | + @property |
| 565 | + @serializable.xml_sequence(2) # Assuming order after name |
| 566 | + @serializable.xml_string(serializable.XmlStringSerializationType.STRING) |
| 567 | + def description(self) -> Optional[str]: |
| 568 | + """ |
| 569 | + The description of the service data. |
| 570 | +
|
| 571 | + Returns: |
| 572 | + `str` if provided else None |
| 573 | + """ |
| 574 | + return self._description |
| 575 | + |
| 576 | + @description.setter |
| 577 | + def description(self, description: Optional[str]) -> None: |
| 578 | + self._description = description |
| 579 | + |
| 580 | + # governance property |
| 581 | + @property |
| 582 | + @serializable.xml_sequence(3) # Assuming order after description |
| 583 | + def governance(self) -> Optional[DataGovernance]: |
| 584 | + """ |
| 585 | + Governance information for the service data. |
| 586 | +
|
| 587 | + Returns: |
| 588 | + `DataGovernance` if provided else None |
| 589 | + """ |
| 590 | + return self._governance |
| 591 | + |
| 592 | + @governance.setter |
| 593 | + def governance(self, governance: Optional[DataGovernance]) -> None: |
| 594 | + self._governance = governance |
| 595 | + |
| 596 | + # source property |
| 597 | + @property |
| 598 | + @serializable.xml_sequence(4) # Assuming order after governance |
| 599 | + def source(self) -> Optional[Iterable[Union[BomRef, XsUri]]]: |
| 600 | + """ |
| 601 | + The source(s) of the service data. |
| 602 | +
|
| 603 | + Returns: |
| 604 | + Iterable of `BomRef` or `XsUri` if provided else None |
| 605 | + """ |
| 606 | + return self._source |
| 607 | + |
| 608 | + @source.setter |
| 609 | + def source(self, source: Optional[Iterable[Union[BomRef, XsUri]]]) -> None: |
| 610 | + self._source = source |
| 611 | + |
| 612 | + # destination property |
| 613 | + @property |
| 614 | + @serializable.xml_sequence(5) # Assuming order after source |
| 615 | + def destination(self) -> Optional[Iterable[Union[BomRef, XsUri]]]: |
| 616 | + """ |
| 617 | + The destination(s) of the service data. |
| 618 | +
|
| 619 | + Returns: |
| 620 | + Iterable of `BomRef` or `XsUri` if provided else None |
| 621 | + """ |
| 622 | + return self._destination |
| 623 | + |
| 624 | + @destination.setter |
| 625 | + def destination(self, destination: Optional[Iterable[Union[BomRef, XsUri]]]) -> None: |
| 626 | + self._destination = destination |
| 627 | + |
| 628 | + def __eq__(self, other: object) -> bool: |
| 629 | + if isinstance(other, DataClassification): |
| 630 | + return hash(other) == hash(self) |
| 631 | + return False |
| 632 | + |
| 633 | + def __lt__(self, other: object) -> bool: |
| 634 | + if isinstance(other, DataClassification): |
| 635 | + return _ComparableTuple(( |
| 636 | + self.flow, self.classification |
| 637 | + )) < _ComparableTuple(( |
| 638 | + other.flow, other.classification |
| 639 | + )) |
| 640 | + return NotImplemented |
| 641 | + |
| 642 | + def __hash__(self) -> int: |
| 643 | + return hash((self.flow, self.classification)) |
| 644 | + |
| 645 | + def __repr__(self) -> str: |
| 646 | + return f'<DataClassification flow={self.flow}>' |
0 commit comments