ToeService.php
1 <?php 2 3 namespace App\Http\Services; 4 5 use App\Events\SpdxUpdate; 6 use App\Jobs\GrypeSpdx; 7 use App\Models\FunctionalityEnvelope; 8 use App\Models\NoCoverDanger; 9 use App\Models\SecurityPolicy; 10 use Exception; 11 use App\Models\TOE; 12 use App\Models\TOEVulnerability; 13 use App\Models\UseEnvelopeHipotesis; 14 use App\Models\User; 15 use Illuminate\Foundation\Bus\DispatchesJobs; 16 use Illuminate\Support\Arr; 17 use Illuminate\Http\Request; 18 use Illuminate\Support\Facades\DB; 19 use Illuminate\Support\Facades\Storage; 20 use Log; 21 22 class ToeService 23 { 24 /** 25 * Search resources 26 * 27 * @return \Illuminate\Http\Response 28 */ 29 public static function searchToes(string $searchString, string $sortField, string $sortDirection, array|null $filters, ?User $user = null) 30 { 31 $toesQuery = TOE::query(); 32 33 if ( 34 isset($user) and 35 !$user->hasAnyRole([ 36 'root', 37 'technical_manager', 38 'quality_manager', 39 'security_manager', 40 'area_manager' 41 ]) 42 ) { 43 $toesQuery->whereHas( 44 'dossier', 45 fn ($query) => $query->whereHas( 46 'users', 47 fn ($query) => $query->where('users.id', $user->id) 48 ) 49 ->orWhereHas( 50 'principalCertifier', 51 fn ($query) => $query->where('users.id', $user->id) 52 ) 53 )->orWhere('created_by', $user->id); 54 } 55 56 if (isset($filters['entity_id']) && Arr::exists($filters, 'entity_id')) { 57 $toesQuery->whereHas('company', function ($query) use ($filters) { 58 $query->where('entities.id', $filters['entity_id']); 59 }); 60 } 61 62 if (isset($filters['withTrashed']) && $filters['withTrashed']) { 63 $toesQuery->withTrashed(); 64 } 65 66 $toesQuery 67 ->where(function ($query) use ($searchString) { 68 $query 69 ->where('name', 'like', '%' . $searchString . '%') 70 ->orWhere('alias', 'like', '%' . $searchString . '%') 71 ->orWhere('version', 'like', '%' . $searchString . '%'); 72 }); 73 74 if (isset($filters['created_at_since']) && $filters['created_at_since']) { 75 $toesQuery->where('created_at', '>=', $filters['created_at_since']); 76 } 77 78 if (isset($filters['created_at_to']) && $filters['created_at_to']) { 79 $toesQuery->where('created_at', '<=', $filters['created_at_to']); 80 } 81 82 if (isset($filters['company']) && $filters['company']) { 83 $toesQuery->whereIn('company_id', $filters['company']); 84 } 85 86 if (isset($filters['country']) && $filters['country']) { 87 $toesQuery->whereIn('country_id', $filters['country']); 88 } 89 90 if (isset($filters['types']) && $filters['types']) { 91 $toesQuery->whereHas('types', function ($query) use ($filters) { 92 $query->whereIn('t_o_e_type_id', $filters['types']); 93 }); 94 } 95 96 if ($sortField && $sortDirection) { 97 $toesQuery->orderBy($sortField, $sortDirection); 98 } 99 100 return $toesQuery; 101 } 102 103 /** 104 * Display a listing of the resource. 105 * 106 * @return \Illuminate\Http\Response 107 */ 108 public static function find(int $toeId) 109 { 110 return TOE::find($toeId); 111 } 112 113 /** 114 * Display a listing of the resource. 115 * 116 * @return \Illuminate\Http\Response 117 */ 118 public static function index() 119 { 120 return TOE::orderBy('name', 'asc')->paginate(10); 121 } 122 123 /** 124 * Create a resource 125 * 126 * @return \Illuminate\Http\Response 127 */ 128 public static function create(array $toeData): bool|Exception 129 { 130 $toe = TOE::create($toeData); 131 132 /* GRYPE is not used in SGOC 133 if ($toe->spdx_path && Storage::exists($toe->spdx_path)) { 134 dispatch(new GrypeSpdx(collect([$toe]))); 135 } 136 */ 137 138 $toe->types()->sync($toeData['types']); 139 140 141 return true; 142 } 143 144 /** 145 * Update a resource 146 * 147 * @return \Illuminate\Http\Response 148 */ 149 public static function update(array $data, int $entityId): bool|Exception 150 { 151 try { 152 $toe = TOE::findOrFail($entityId); 153 154 $toe->update($data); 155 $toe->types()->sync($data['types']); 156 157 return true; 158 } catch (Exception $e) { 159 logger()->error($e->getMessage()); 160 throw new Exception(__('toes.toe.notifications.update.error.message')); 161 return false; 162 } 163 } 164 165 166 /** 167 * Destroy a resource 168 * 169 * @return \Illuminate\Http\Response 170 */ 171 public static function remove(int $userId) 172 { 173 try { 174 DB::beginTransaction(); 175 TOE::destroy($userId); 176 DB::commit(); 177 178 return true; 179 } catch (Exception $e) { 180 DB::rollBack(); 181 throw new Exception(__('toes.toe.notifications.remove.error.message')); 182 } 183 } 184 185 /** 186 * Restore a resource 187 * 188 * @return \Illuminate\Http\Response 189 */ 190 public static function restore(int $userId) 191 { 192 try { 193 DB::beginTransaction(); 194 TOE::withTrashed()->find($userId)->restore(); 195 DB::commit(); 196 197 return true; 198 } catch (Exception $e) { 199 DB::rollBack(); 200 throw new Exception(__('toes.toe.notifications.remove.error.message')); 201 } 202 } 203 204 public static function getToes() 205 { 206 return TOE::query() 207 ->select('id', 'name') 208 ->orderBy('name') 209 ->get(); 210 } 211 212 public static function getCertificationFields(string $sortField, string $sortDirection, int $toeId, string $model) 213 { 214 $TOE = TOE::find($toeId); 215 216 $query = match ($model) { 217 'SecurityPolicy' => $TOE->securityPolicies(), 218 'UseEnvelopeHipotesis' => $TOE->useEnvelopeHipoteses(), 219 'FunctionalityEnvelope' => $TOE->functionalityEnvelopes(), 220 'NoCoverDanger' => $TOE->noCoverDangers(), 221 }; 222 223 if ($sortField && $sortDirection) { 224 $query->orderBy($sortField, $sortDirection); 225 } 226 227 return $query; 228 } 229 230 public static function getCertificationField(string $model, int $entityId) 231 { 232 return match ($model) { 233 'SecurityPolicy' => SecurityPolicy::findOrFail($entityId), 234 'UseEnvelopeHipotesis' => UseEnvelopeHipotesis::findOrFail($entityId), 235 'FunctionalityEnvelope' => FunctionalityEnvelope::findOrFail($entityId), 236 'NoCoverDanger' => NoCoverDanger::findOrFail($entityId), 237 }; 238 } 239 240 public static function updateOrCreateCertificationField(array $data, $model, ?int $entityId = null) 241 { 242 243 $class = "App\\Models\\" . $model; 244 return $class::updateOrCreate([ 245 'id' => $entityId, 246 'toe_id' => $data['toe_id'], 247 ], [ 248 'toe_id' => $data['toe_id'], 249 'name' => $data['name'], 250 'description' => $data['description'], 251 ]); 252 } 253 254 public static function removeCertificationField(string $model, int $entityId) 255 { 256 try { 257 DB::beginTransaction(); 258 Log::error($model); 259 Log::error($entityId); 260 match ($model) { 261 'SecurityPolicy' => SecurityPolicy::destroy($entityId), 262 'UseEnvelopeHipotesis' => UseEnvelopeHipotesis::destroy($entityId), 263 'FunctionalityEnvelope' => FunctionalityEnvelope::destroy($entityId), 264 'NoCoverDanger' => NoCoverDanger::destroy($entityId), 265 }; 266 267 DB::commit(); 268 269 return true; 270 } catch (Exception $e) { 271 DB::rollBack(); 272 throw new Exception(__('toes.toe.certification-field.notifications.remove.error.message')); 273 } 274 } 275 276 public static function updateAndCreateRules() 277 { 278 return [ 279 'toe.name' => 'required|min:2', 280 // Deprecated 281 // 'toe.types' => 'required', 282 'toe.product_system' => 'required', 283 'toe.development_address' => 'required', 284 'toe.company_id' => 'required', 285 'toe.country_id' => 'required', 286 287 // Optional 288 'toe.description' => 'nullable|string', 289 'toe.commercial_name' => 'nullable|string|max:255', 290 'toe.evaluation_target' => 'nullable|string|max:255', 291 'toe.usage_dimension' => 'nullable', 292 'toe.sectorial_dimensions' => 'nullable', 293 'toe.sectorial_dimensions.*' => 'nullable', 294 'toe.technological_dimensions' => 'nullable', 295 'toe.technological_dimensions.*' => 'nullable|string|max:255', 296 'toe.cyber_security_info_url' => 'nullable|url', 297 'toe.guidance_url' => 'nullable|url', 298 'toe.period_security_support' => 'nullable|integer|min:1', 299 'toe.provider_contact_vulnerability_url' => 'nullable|url', 300 'toe.vulnerability_notifications' => 'nullable|string|max:255', 301 'toe.publicly_disclosed_url' => 'nullable|url', 302 'toe.version' => 'nullable|string|max:255', 303 'toe.is_certified' => 'nullable|boolean', 304 ]; 305 } 306 }