Skip to content

Commit a9fa044

Browse files
committed
Add models for Incidents.
1 parent 7cf0356 commit a9fa044

File tree

4 files changed

+212
-1
lines changed

4 files changed

+212
-1
lines changed

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ verify_ssl = true
55

66
[packages]
77
pygitguardian = { editable = true, path = "." }
8+
strenum = "*"
89

910
[dev-packages]
1011
black = "==22.3.0"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from dataclasses import dataclass, field
2+
from datetime import datetime
3+
from typing import List, Optional, Type, Union, cast
4+
5+
from marshmallow_dataclass import class_schema
6+
7+
from pygitguardian.incident_models.constants import (
8+
IncidentIgnoreReason,
9+
IncidentSeverity,
10+
IncidentStatus,
11+
IncidentTag,
12+
IncidentValidity,
13+
OccurrenceKind,
14+
OccurrencePresence,
15+
)
16+
from pygitguardian.models import Base, BaseSchema, FromDictMixin
17+
from pygitguardian.source_models import Source
18+
19+
20+
@dataclass
21+
class Detector(Base, FromDictMixin):
22+
name: str
23+
display_name: str
24+
nature: str
25+
family: str
26+
detector_group_name: str
27+
detector_group_display_name: str
28+
29+
30+
DetectorSchema = cast(Type[BaseSchema], class_schema(Detector, BaseSchema))
31+
Detector.SCHEMA = DetectorSchema()
32+
33+
34+
@dataclass
35+
class Match(Base, FromDictMixin):
36+
name: str
37+
indice_start: int
38+
indice_end: int
39+
pre_line_start: Optional[int]
40+
pre_line_end: Optional[int]
41+
post_line_start: Optional[int]
42+
post_line_end: Optional[int]
43+
44+
45+
MatchSchema = cast(Type[BaseSchema], class_schema(Match, BaseSchema))
46+
Match.SCHEMA = MatchSchema()
47+
48+
49+
@dataclass
50+
class Occurrence(Base, FromDictMixin):
51+
id: int
52+
incident_id: int
53+
kind: OccurrenceKind = field(metadata={"by_value": True})
54+
sha: str
55+
source: Source
56+
author_name: str
57+
author_info: str
58+
date: datetime
59+
presence: OccurrencePresence = field(metadata={"by_value": True})
60+
url: str
61+
matches: List[Match]
62+
filepath: str
63+
64+
65+
OccurrenceSchema = cast(Type[BaseSchema], class_schema(Occurrence, BaseSchema))
66+
Occurrence.SCHEMA = OccurrenceSchema()
67+
68+
69+
@dataclass
70+
class Incident(Base, FromDictMixin):
71+
id: int
72+
date: datetime
73+
detector: Detector
74+
secret_hash: str
75+
gitguardian_url: str
76+
regression: bool
77+
status: IncidentStatus = field(metadata={"by_value": True})
78+
assignee_email: Optional[str]
79+
occurrences_count: int
80+
occurrences: Optional[List[Occurrence]]
81+
ignore_reason: Optional[IncidentIgnoreReason] = field(metadata={"by_value": True})
82+
ignored_at: Optional[datetime]
83+
secret_revoked: bool
84+
severity: IncidentSeverity = field(metadata={"by_value": True})
85+
validity: IncidentValidity = field(metadata={"by_value": True})
86+
resolved_at: Optional[datetime]
87+
share_url: Optional[str]
88+
tags: List[IncidentTag] = field(metadata={"by_value": True})
89+
90+
def __int__(self):
91+
return self.id
92+
93+
94+
IncidentSchema = cast(Type[BaseSchema], class_schema(Incident, BaseSchema))
95+
Incident.SCHEMA = IncidentSchema()
96+
97+
98+
@dataclass
99+
class Link:
100+
url: str
101+
rel: str
102+
103+
104+
@dataclass
105+
class Links:
106+
next: Optional[Link]
107+
prev: Optional[Link]
108+
109+
110+
@dataclass
111+
class ListIncidentResult(Base, FromDictMixin):
112+
incidents: List[Incident]
113+
links: Optional[Links] = None
114+
115+
116+
ListIncidentResultSchema = cast(
117+
Type[BaseSchema], class_schema(ListIncidentResult, BaseSchema)
118+
)
119+
ListIncidentResult.SCHEMA = ListIncidentResultSchema()
120+
121+
122+
@dataclass
123+
class SharedIncidentDetails(Base, FromDictMixin):
124+
incident_id: int
125+
share_url: str
126+
feedback_collection: bool
127+
auto_healing: bool
128+
token: str
129+
expire_at: Optional[datetime] = None
130+
revoked_at: Optional[datetime] = None
131+
132+
133+
SharedIncidentDetailsSchema = cast(
134+
Type[BaseSchema], class_schema(SharedIncidentDetails, BaseSchema)
135+
)
136+
SharedIncidentDetails.SCHEMA = SharedIncidentDetailsSchema()
137+
138+
IncidentIdOrIncident = Union[int, Incident]
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from enum import auto
2+
3+
from strenum import LowercaseStrEnum, MacroCaseStrEnum, SnakeCaseStrEnum, StrEnum
4+
5+
6+
class IncidentIgnoreReason(SnakeCaseStrEnum):
7+
TEST_CREDENTIAL = auto()
8+
FALSE_POSITIVE = auto()
9+
LOW_RISK = auto()
10+
11+
12+
class IncidentOrdering(StrEnum):
13+
DATE_ASC = "date"
14+
DATE_DESC = "-date"
15+
RESOLVED_AT_ASC = "resolved_at"
16+
RESOLVED_AT_DESC = "-resolved_at"
17+
IGNORED_AT_ASC = "ignored_at"
18+
IGNORED_AT_DESC = "-ignored_at"
19+
20+
21+
class IncidentPermission(LowercaseStrEnum):
22+
CAN_VIEW = auto()
23+
CAN_EDIT = auto()
24+
FULL_ACCESS = auto()
25+
26+
27+
class IncidentSeverity(SnakeCaseStrEnum):
28+
CRITICAL = auto()
29+
HIGH = auto()
30+
MEDIUM = auto()
31+
LOW = auto()
32+
INFO = auto()
33+
UNKNOWN = auto()
34+
35+
36+
class IncidentStatus(MacroCaseStrEnum):
37+
IGNORED = auto()
38+
TRIGGERED = auto()
39+
ASSIGNED = auto()
40+
RESOLVED = auto()
41+
42+
43+
class IncidentTag(MacroCaseStrEnum):
44+
DEFAULT_BRANCH = auto()
45+
FROM_HISTORICAL_SCAN = auto()
46+
IGNORED_IN_CHECK_RUN = auto()
47+
PUBLIC = auto()
48+
PUBLICLY_EXPOSED = auto()
49+
PUBLICLY_LEAKED = auto()
50+
REGRESSION = auto()
51+
SENSITIVE_FILE = auto()
52+
TEST_FILE = auto()
53+
54+
55+
class IncidentValidity(SnakeCaseStrEnum):
56+
VALID = auto()
57+
INVALID = auto()
58+
FAILED_TO_CHECK = auto()
59+
NO_CHECKER = auto()
60+
UNKNOWN = auto()
61+
62+
63+
class OccurrenceKind(LowercaseStrEnum):
64+
REALTIME = auto()
65+
HISTORICAL = auto()
66+
67+
68+
class OccurrencePresence(SnakeCaseStrEnum):
69+
present = auto()
70+
removed = auto()

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ def get_version() -> str:
3434
install_requires=[
3535
"marshmallow>=3.5, <4",
3636
"requests>=2, <3",
37-
"marshmallow-dataclass >=8.5.8, <8.6.0",
37+
"marshmallow-dataclass[enum,union] >=8.5.8, <8.6.0",
3838
"typing-extensions",
39+
"urllib3<2",
40+
"strenum",
3941
],
4042
include_package_data=True,
4143
zip_safe=True,

0 commit comments

Comments
 (0)