Coverage for src/meshadmin/server/project/middleware.py: 39%

142 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-10 16:08 +0200

1from django.urls import resolve, reverse 

2 

3from meshadmin.server.networks.models import ( 

4 CA, 

5 ConfigRollout, 

6 Group, 

7 Host, 

8 Network, 

9 Rule, 

10 Template, 

11) 

12 

13 

14class BreadcrumbMiddleware: 

15 def __init__(self, get_response): 

16 self.get_response = get_response 

17 

18 def __call__(self, request): 

19 response = self.get_response(request) 

20 return response 

21 

22 def process_template_response(self, request, response): 

23 if request.htmx: 

24 return response 

25 

26 if not hasattr(response, "context_data"): 

27 return response 

28 

29 # Start with the base networks link 

30 breadcrumbs = [{"label": "Networks", "url": reverse("networks:network-list")}] 

31 

32 # Get resolved URL info 

33 resolved = resolve(request.path_info) 

34 url_name = resolved.url_name 

35 kwargs = resolved.kwargs 

36 context = response.context_data 

37 

38 # Handle network-specific paths 

39 if "pk" in kwargs and url_name in [ 

40 "network-detail", 

41 "network-edit", 

42 "network-delete", 

43 ]: 

44 network_id = kwargs["pk"] 

45 network = self._get_network_by_id(network_id, context) 

46 if network: 

47 breadcrumbs.append( 

48 { 

49 "label": network.name, 

50 "url": reverse( 

51 "networks:network-detail", kwargs={"pk": network.pk} 

52 ), 

53 } 

54 ) 

55 if url_name == "network-edit": 

56 breadcrumbs.append({"label": "Edit", "url": "#"}) 

57 elif url_name == "network-delete": 

58 breadcrumbs.append({"label": "Delete", "url": "#"}) 

59 

60 # Handle network creation 

61 elif url_name == "network-create": 

62 breadcrumbs.append({"label": "Create Network", "url": "#"}) 

63 

64 # Handle network-related entities (host, template, group, ca, rollout, membership) 

65 elif "network_id" in kwargs: 

66 network_id = kwargs["network_id"] 

67 network = self._get_network_by_id(network_id, context) 

68 

69 if network: 

70 # Add network link with appropriate section anchor 

71 section_anchor = "" 

72 if "host" in url_name: 

73 section_anchor = "#hosts-section" 

74 elif "template" in url_name: 

75 section_anchor = "#templates-section" 

76 elif "group" in url_name or "security-group" in url_name: 

77 section_anchor = "#groups-section" 

78 elif "ca" in url_name: 

79 section_anchor = "#cas-section" 

80 elif "rollout" in url_name: 

81 section_anchor = "#rollouts-section" 

82 elif "member" in url_name or "member" in url_name: 

83 section_anchor = "#members-section" 

84 

85 breadcrumbs.append( 

86 { 

87 "label": network.name, 

88 "url": reverse( 

89 "networks:network-detail", kwargs={"pk": network.pk} 

90 ) 

91 + section_anchor, 

92 } 

93 ) 

94 

95 # Add entity-specific breadcrumbs based on URL pattern 

96 if "host" in url_name: 

97 breadcrumbs.append({"label": "Create Host", "url": "#"}) 

98 elif "template" in url_name: 

99 breadcrumbs.append({"label": "Create Template", "url": "#"}) 

100 elif "group" in url_name: 

101 breadcrumbs.append({"label": "Create Group", "url": "#"}) 

102 elif "ca" in url_name: 

103 breadcrumbs.append({"label": "Create CA", "url": "#"}) 

104 elif "rollout" in url_name: 

105 breadcrumbs.append({"label": "Create Rollout", "url": "#"}) 

106 elif "add" in url_name: 

107 breadcrumbs.append({"label": "Add Member", "url": "#"}) 

108 

109 # Handle entity-specific paths (without network_id in URL) 

110 elif "pk" in kwargs: 

111 entity_id = kwargs["pk"] 

112 

113 # Handle Host 

114 if url_name in [ 

115 "host-detail", 

116 "host-edit", 

117 "host-delete", 

118 ]: 

119 host = self._get_object_by_id(Host, entity_id, context) 

120 if host: 

121 network = host.network 

122 breadcrumbs.append( 

123 { 

124 "label": network.name, 

125 "url": reverse( 

126 "networks:network-detail", kwargs={"pk": network.pk} 

127 ) 

128 + "#hosts-section", 

129 } 

130 ) 

131 breadcrumbs.append( 

132 { 

133 "label": host.name, 

134 "url": reverse( 

135 "networks:host-detail", kwargs={"pk": host.pk} 

136 ), 

137 } 

138 ) 

139 

140 # Add action breadcrumb 

141 if "edit" in url_name: 

142 breadcrumbs.append({"label": "Edit", "url": "#"}) 

143 elif "delete" in url_name: 

144 breadcrumbs.append({"label": "Delete", "url": "#"}) 

145 

146 # Handle Template 

147 elif url_name in ["template-detail", "template-edit", "template-delete"]: 

148 template = self._get_object_by_id(Template, entity_id, context) 

149 if template: 

150 network = template.network 

151 breadcrumbs.append( 

152 { 

153 "label": network.name, 

154 "url": reverse( 

155 "networks:network-detail", kwargs={"pk": network.pk} 

156 ) 

157 + "#templates-section", 

158 } 

159 ) 

160 breadcrumbs.append( 

161 { 

162 "label": template.name, 

163 "url": reverse( 

164 "networks:template-detail", kwargs={"pk": template.pk} 

165 ), 

166 } 

167 ) 

168 

169 # Add action breadcrumb 

170 if "edit" in url_name: 

171 breadcrumbs.append({"label": "Edit", "url": "#"}) 

172 elif "delete" in url_name: 

173 breadcrumbs.append({"label": "Delete", "url": "#"}) 

174 

175 # Handle Group 

176 elif url_name in ["group-detail", "group-edit", "group-delete"]: 

177 group = self._get_object_by_id(Group, entity_id, context) 

178 if group: 

179 network = group.network 

180 breadcrumbs.append( 

181 { 

182 "label": network.name, 

183 "url": reverse( 

184 "networks:network-detail", kwargs={"pk": network.pk} 

185 ) 

186 + "#groups-section", 

187 } 

188 ) 

189 breadcrumbs.append( 

190 { 

191 "label": group.name, 

192 "url": reverse( 

193 "networks:group-detail", kwargs={"pk": group.pk} 

194 ), 

195 } 

196 ) 

197 

198 # Add action breadcrumb 

199 if "edit" in url_name: 

200 breadcrumbs.append({"label": "Edit", "url": "#"}) 

201 elif "delete" in url_name: 

202 breadcrumbs.append({"label": "Delete", "url": "#"}) 

203 

204 # Handle CA 

205 elif url_name in ["ca-detail", "ca-edit", "ca-delete"]: 

206 ca = self._get_object_by_id(CA, entity_id, context) 

207 if ca: 

208 network = ca.network 

209 breadcrumbs.append( 

210 { 

211 "label": network.name, 

212 "url": reverse( 

213 "networks:network-detail", kwargs={"pk": network.pk} 

214 ) 

215 + "#cas-section", 

216 } 

217 ) 

218 breadcrumbs.append( 

219 { 

220 "label": ca.name, 

221 "url": reverse("networks:ca-detail", kwargs={"pk": ca.pk}), 

222 } 

223 ) 

224 

225 # Add action breadcrumb 

226 if "edit" in url_name: 

227 breadcrumbs.append({"label": "Edit", "url": "#"}) 

228 elif "delete" in url_name: 

229 breadcrumbs.append({"label": "Delete", "url": "#"}) 

230 

231 # Handle Rule 

232 elif url_name in ["rule-detail", "rule-edit", "rule-delete"]: 

233 rule = self._get_object_by_id(Rule, entity_id, context) 

234 if rule: 

235 security_group = rule.security_group 

236 network = security_group.network 

237 breadcrumbs.append( 

238 { 

239 "label": network.name, 

240 "url": reverse( 

241 "networks:network-detail", kwargs={"pk": network.pk} 

242 ) 

243 + "#groups-section", 

244 } 

245 ) 

246 if security_group: 

247 breadcrumbs.append( 

248 { 

249 "label": security_group.name, 

250 "url": reverse( 

251 "networks:group-detail", 

252 kwargs={"pk": security_group.pk}, 

253 ), 

254 } 

255 ) 

256 breadcrumbs.append( 

257 { 

258 "label": f"Rule {rule.pk}", 

259 "url": reverse( 

260 "networks:rule-detail", kwargs={"pk": rule.pk} 

261 ), 

262 } 

263 ) 

264 

265 # Add action breadcrumb 

266 if "edit" in url_name: 

267 breadcrumbs.append({"label": "Edit", "url": "#"}) 

268 elif "delete" in url_name: 

269 breadcrumbs.append({"label": "Delete", "url": "#"}) 

270 

271 # Handle Rollout 

272 elif url_name in [ 

273 "rollout-detail", 

274 "rollout-edit", 

275 "rollout-delete", 

276 ]: 

277 rollout = self._get_object_by_id(ConfigRollout, entity_id, context) 

278 if rollout: 

279 network = rollout.network 

280 breadcrumbs.append( 

281 { 

282 "label": network.name, 

283 "url": reverse( 

284 "networks:network-detail", kwargs={"pk": network.pk} 

285 ) 

286 + "#rollouts-section", 

287 } 

288 ) 

289 breadcrumbs.append( 

290 { 

291 "label": f"Rollout {rollout.pk}", 

292 "url": reverse( 

293 "networks:rollout-detail", kwargs={"pk": rollout.pk} 

294 ), 

295 } 

296 ) 

297 

298 # Add action breadcrumb 

299 if "edit" in url_name: 

300 breadcrumbs.append({"label": "Edit", "url": "#"}) 

301 elif "delete" in url_name: 

302 breadcrumbs.append({"label": "Delete", "url": "#"}) 

303 

304 # Add breadcrumbs to context 

305 response.context_data["breadcrumbs"] = breadcrumbs 

306 return response 

307 

308 def _get_network_by_id(self, network_id, context): 

309 """ 

310 Helper to get a network by ID from context or database 

311 """ 

312 if ( 

313 "network" in context 

314 and hasattr(context["network"], "pk") 

315 and context["network"].pk == network_id 

316 ): 

317 return context["network"] 

318 

319 if ( 

320 "object" in context 

321 and isinstance(context["object"], Network) 

322 and context["object"].pk == network_id 

323 ): 

324 return context["object"] 

325 

326 try: 

327 return Network.objects.get(id=network_id) 

328 except Network.DoesNotExist: 

329 return None 

330 

331 def _get_object_by_id(self, model_class, object_id, context): 

332 """ 

333 Helper to get an object by ID from context or database 

334 """ 

335 if ( 

336 "object" in context 

337 and isinstance(context["object"], model_class) 

338 and context["object"].pk == object_id 

339 ): 

340 return context["object"] 

341 

342 try: 

343 return model_class.objects.get(id=object_id) 

344 except model_class.DoesNotExist: 

345 return None