1919 Any ,
2020 Callable ,
2121 Dict ,
22+ List ,
2223 Optional ,
2324 Union ,
2425)
@@ -67,6 +68,26 @@ def from_score(score: float) -> "Rating":
6768 "Uncategorized score, score should be in the following interval [0,10]."
6869 )
6970
71+ @staticmethod
72+ def bandit_rating (score : float ) -> "Rating" :
73+ score = round (score , 3 )
74+ if score <= 0.2 :
75+ return Rating .F
76+ elif 0.2 < score <= 1.6 :
77+ return Rating .E
78+ elif 1.6 < score <= 3 :
79+ return Rating .D
80+ elif 3 < score <= 4.4 :
81+ return Rating .C
82+ elif 4.4 < score <= 5.8 :
83+ return Rating .B
84+ elif 5.8 < score <= 6 :
85+ return Rating .A
86+ else :
87+ raise ValueError (
88+ "Uncategorized score, score should be in the following interval [0,6]."
89+ )
90+
7091
7192@dataclass (frozen = True )
7293class Report :
@@ -124,8 +145,27 @@ def reliability() -> Rating:
124145 return Rating .NotAvailable
125146
126147
127- def security () -> Rating :
128- return Rating .NotAvailable
148+ def security (file : Union [str , Path ]) -> Rating :
149+ with open (file ) as json_file :
150+ security_lint = json .load (json_file )
151+ return Rating .bandit_rating (_bandit_scoring (security_lint ["results" ]))
152+
153+
154+ def _bandit_scoring (ratings : List [Dict [str , Any ]]) -> float :
155+ def char (value : str , default : str = "H" ) -> str :
156+ if value in ["HIGH" , "MEDIUM" , "LOW" ]:
157+ return value [0 ]
158+ return default
159+
160+ weight = {"LL" : 1 / 18 , "LM" : 1 / 15 , "LH" : 1 / 12 , "ML" : 1 / 9 , "MM" : 1 / 6 , "MH" : 1 / 3 }
161+ exp = 0.0
162+ for infos in ratings :
163+ severity = infos ["issue_severity" ]
164+ if severity == "HIGH" :
165+ return 0.0
166+ index = char (severity ) + char (infos ["issue_confidence" ])
167+ exp += weight [index ]
168+ return 6 * (2 ** - exp )
129169
130170
131171def technical_debt () -> Rating :
@@ -137,14 +177,15 @@ def create_report(
137177 date : Optional [datetime .datetime ] = None ,
138178 coverage_report : Union [str , Path ] = ".coverage" ,
139179 pylint_report : Union [str , Path ] = ".lint.txt" ,
180+ bandit_report : Union [str , Path ] = ".security.json" ,
140181) -> Report :
141182 return Report (
142183 commit = commit ,
143184 date = date if date is not None else datetime .datetime .now (),
144185 coverage = total_coverage (coverage_report ),
145186 maintainability = maintainability (pylint_report ),
146187 reliability = reliability (),
147- security = security (),
188+ security = security (bandit_report ),
148189 technical_debt = technical_debt (),
149190 )
150191
0 commit comments