|
1 | 1 | import datetime |
2 | | -import json |
3 | 2 |
|
4 | 3 | import pymongo.errors |
5 | 4 | from bson import ObjectId |
@@ -284,52 +283,49 @@ def list_access_tokens(): |
284 | 283 |
|
285 | 284 | @ADMIN.route("/groups", methods=["GET"]) |
286 | 285 | def get_groups(): |
287 | | - groups_data = [] |
288 | | - for group_doc in flask_mongo.db.groups.find(): |
289 | | - group_doc["immutable_id"] = str(group_doc["_id"]) |
290 | | - |
291 | | - group_data = json.loads(Group(**group_doc).json()) |
292 | | - |
293 | | - # TODO: remove or refactor into $lookup |
294 | | - group_members = list( |
295 | | - flask_mongo.db.users.find( |
296 | | - {"group_ids": group_doc["_id"]}, {"_id": 1, "display_name": 1, "contact_email": 1} |
297 | | - ) |
298 | | - ) |
299 | | - group_data["members"] = [ |
| 286 | + # Lookup members from users collection: find all those that refer to this group ID in their groups->immutable_id field |
| 287 | + members_lookup = { |
| 288 | + "from": "users", |
| 289 | + "let": {"group_id": "$_id"}, |
| 290 | + "pipeline": [ |
300 | 291 | { |
301 | | - "immutable_id": str(member["_id"]), |
302 | | - "display_name": member.get("display_name", ""), |
303 | | - "contact_email": member.get("contact_email", ""), |
304 | | - } |
305 | | - for member in group_members |
306 | | - ] |
| 292 | + "$match": { |
| 293 | + "$expr": {"$in": ["$$group_id", {"$ifNull": ["$groups.immutable_id", []]}]} |
| 294 | + } |
| 295 | + }, |
| 296 | + { |
| 297 | + "$project": { |
| 298 | + "_id": 1, |
| 299 | + "display_name": 1, |
| 300 | + "contact_email": 1, |
| 301 | + } |
| 302 | + }, |
| 303 | + ], |
| 304 | + "as": "members", |
| 305 | + } |
307 | 306 |
|
308 | | - # TODO: remove or refactor into $lookup |
309 | | - if group_doc.get("managers"): |
310 | | - admin_ids = [ObjectId(admin_id) for admin_id in group_doc["managers"]] |
311 | | - managers = list( |
312 | | - flask_mongo.db.users.find( |
313 | | - {"_id": {"$in": admin_ids}}, {"_id": 1, "display_name": 1, "contact_email": 1} |
314 | | - ) |
315 | | - ) |
316 | | - group_data["managers"] = [ |
317 | | - { |
318 | | - "immutable_id": str(admin["_id"]), |
319 | | - "display_name": admin.get("display_name", ""), |
320 | | - "contact_email": admin.get("contact_email", ""), |
| 307 | + # Lookup managers from users collection: find all those referred to by ID in this group under the managers field |
| 308 | + managers_lookup = { |
| 309 | + "from": "users", |
| 310 | + "let": {"manager_ids": "$managers"}, |
| 311 | + "pipeline": [ |
| 312 | + {"$match": {"$expr": {"$in": ["$_id", {"$ifNull": ["$$manager_ids", []]}]}}}, |
| 313 | + { |
| 314 | + "$project": { |
| 315 | + "_id": 1, |
| 316 | + "display_name": 1, |
| 317 | + "contact_email": 1, |
321 | 318 | } |
322 | | - for admin in managers |
323 | | - ] |
| 319 | + }, |
| 320 | + ], |
| 321 | + "as": "managers", |
| 322 | + } |
324 | 323 |
|
325 | | - groups_data.append(group_data) |
| 324 | + group_docs = flask_mongo.db.groups.aggregate( |
| 325 | + [{"$match": {}}, {"$lookup": members_lookup}, {"$lookup": managers_lookup}] |
| 326 | + ) |
326 | 327 |
|
327 | | - return jsonify( |
328 | | - { |
329 | | - "status": "success", |
330 | | - "data": groups_data, |
331 | | - } |
332 | | - ), 200 |
| 328 | + return jsonify({"status": "success", "data": [Group(**d).dict() for d in group_docs]}), 200 |
333 | 329 |
|
334 | 330 |
|
335 | 331 | @ADMIN.route("/groups", methods=["PUT"]) |
@@ -399,6 +395,9 @@ def update_group(group_immutable_id: str): |
399 | 395 | if "description" in request_json: |
400 | 396 | update_data["description"] = request_json["description"] |
401 | 397 |
|
| 398 | + if "group_id" in request_json: |
| 399 | + update_data["group_id"] = request_json["group_id"] |
| 400 | + |
402 | 401 | if "managers" in request_json: |
403 | 402 | update_data["managers"] = [ObjectId(u) for u in request_json["managers"]] |
404 | 403 | bad_managers = [ |
|
0 commit comments