Mercurial > prosody-modules
comparison mod_http_admin_api/mod_http_admin_api.lua @ 6329:5571c75a4fed
mod_http_admin_api: Unify error reporting around util.error
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Wed, 01 Oct 2025 11:25:57 +0100 |
| parents | 4b52d579bc70 |
| children | 4e63151010bf |
comparison
equal
deleted
inserted
replaced
| 6328:187b957dc528 | 6329:5571c75a4fed |
|---|---|
| 30 local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; | 30 local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; |
| 31 local xmlns_nick = "http://jabber.org/protocol/nick"; | 31 local xmlns_nick = "http://jabber.org/protocol/nick"; |
| 32 | 32 |
| 33 local deleted_users = module:open_store("accounts_cleanup"); | 33 local deleted_users = module:open_store("accounts_cleanup"); |
| 34 | 34 |
| 35 local errors = require "util.error".init(module.name, "https://prosody.im/protocol/errors", { | |
| 36 ["feature-not-implemented"] = { "cancel", "feature-not-implemented", "Feature not implemented" }; | |
| 37 ["unknown-invite-type"] = { "cancel", "bad-request", "Unknown invitation type" }; | |
| 38 ["invite-creation-failed"] = { "cancel", "internal-server-error", "Failed to create invitation" }; | |
| 39 ["invalid-json"] = { "modify", "bad-request", "Invalid JSON submitted" }; | |
| 40 ["user-not-found"] = { "cancel", "item-not-found", "User not found", "user-not-found" }; | |
| 41 | |
| 42 -- From mod_groups_internal | |
| 43 ["group-name-required"] = { "modify", "bad-request", "Group name required", "group-name-required" }; | |
| 44 ["group-not-found"] = { "cancel", "item-not-found", "Group not found", "group-not-found" }; | |
| 45 | |
| 46 -- Generic | |
| 47 ["conflict"] = { "cancel", "conflict", "Resource already exists" }; | |
| 48 ["internal-server-error"] = { "wait", "internal-server-error", "Internal server error" }; | |
| 49 ["service-unavailable"] = { "cancel", "service-unavailable", "Unable to perform the requested action" }; | |
| 50 ["bad-request"] = { "cancel", "bad-request", "Invalid request" }; | |
| 51 }); | |
| 52 | |
| 35 local function check_credentials(request) | 53 local function check_credentials(request) |
| 36 local auth_type, auth_data = string.match(request.headers.authorization or "", "^(%S+)%s(.+)$"); | 54 local auth_type, auth_data = string.match(request.headers.authorization or "", "^(%S+)%s(.+)$"); |
| 37 if not (auth_type and auth_data) then | 55 if not (auth_type and auth_data) then |
| 38 return false; | 56 return false; |
| 39 end | 57 end |
| 67 routes[route] = function (event, ...) | 85 routes[route] = function (event, ...) |
| 68 local permit, code = check_request_auth(event); | 86 local permit, code = check_request_auth(event); |
| 69 if not permit then | 87 if not permit then |
| 70 return code; | 88 return code; |
| 71 end | 89 end |
| 72 return handler(event, ...); | 90 return errors.coerce(handler(event, ...)); |
| 73 end; | 91 end; |
| 74 end | 92 end |
| 75 return routes; | 93 return routes; |
| 76 end | 94 end |
| 77 | 95 |
| 164 groups = options.groups; | 182 groups = options.groups; |
| 165 roles = options.roles; | 183 roles = options.roles; |
| 166 note = options.note; | 184 note = options.note; |
| 167 }, options.ttl); | 185 }, options.ttl); |
| 168 else | 186 else |
| 169 return 400; | 187 return nil, "unknown-invite-type"; |
| 170 end | 188 end |
| 171 if not invite then | 189 if not invite then |
| 172 return 500; | 190 return nil, "invite-creation-failed"; |
| 173 end | 191 end |
| 174 event.response.headers["Content-Type"] = json_content_type; | 192 event.response.headers["Content-Type"] = json_content_type; |
| 175 return json.encode(token_info_to_invite_info(invite)); | 193 return json.encode(token_info_to_invite_info(invite)); |
| 176 end | 194 end |
| 177 | 195 |
| 453 | 471 |
| 454 function patch_user(event, username) | 472 function patch_user(event, username) |
| 455 if not username then return; end | 473 if not username then return; end |
| 456 | 474 |
| 457 local current_user = get_user_info(username); | 475 local current_user = get_user_info(username); |
| 458 if not current_user then return 404; end | 476 if not current_user then return nil, "user-not-found"; end |
| 459 | 477 |
| 460 local request = event.request; | 478 local request = event.request; |
| 461 if request.headers.content_type ~= json_content_type | 479 if request.headers.content_type ~= json_content_type |
| 462 or (not request.body or #request.body == 0) then | 480 or (not request.body or #request.body == 0) then |
| 463 return 400; | 481 return nil, "invalid-json"; |
| 464 end | 482 end |
| 465 local new_user = json.decode(event.request.body); | 483 local new_user = json.decode(event.request.body); |
| 466 if not new_user then | 484 if not new_user then |
| 467 return 400; | 485 return nil, "invalid-json"; |
| 468 end | 486 end |
| 469 | 487 |
| 470 local updated_attributes = set.new(array.collect(it.keys(new_user))); | 488 local updated_attributes = set.new(array.collect(it.keys(new_user))); |
| 471 if not (updated_attributes - writable_user_attributes):empty() then | 489 if not (updated_attributes - writable_user_attributes):empty() then |
| 472 module:log("warn", "Unable to service PATCH user request, unsupported attributes: %s", (updated_attributes - writable_user_attributes)); | 490 module:log("warn", "Unable to service PATCH user request, unsupported attributes: %s", (updated_attributes - writable_user_attributes)); |
| 473 return 400; | 491 return 400; |
| 474 end | 492 end |
| 475 | 493 |
| 476 if new_user.enabled ~= nil and new_user.enabled ~= current_user.enabled then | 494 if new_user.enabled ~= nil and new_user.enabled ~= current_user.enabled then |
| 477 if not user_attribute_writers.enabled(username, new_user.enabled) then | 495 local ok, err = user_attribute_writers.enabled(username, new_user.enabled); |
| 478 return 500; | 496 if not ok then |
| 497 return nil, err; | |
| 479 end | 498 end |
| 480 end | 499 end |
| 481 | 500 |
| 482 return 200; | 501 return 200; |
| 483 end | 502 end |
| 512 }); | 531 }); |
| 513 end | 532 end |
| 514 | 533 |
| 515 if new_user.role then | 534 if new_user.role then |
| 516 if not usermanager.set_user_role then | 535 if not usermanager.set_user_role then |
| 517 return 500, "feature-not-implemented"; | 536 return nil, "feature-not-implemented"; |
| 518 end | 537 end |
| 519 if not usermanager.set_user_role(username, module.host, new_user.role) then | 538 local role, role_err = usermanager.set_user_role(username, module.host, new_user.role); |
| 520 module:log("error", "failed to set role %s for %s", new_user.role, username); | 539 if not role then |
| 521 return 500; | 540 module:log("error", "failed to set role %s for %s: ", new_user.role, username, role_err); |
| 541 return nil, role_err; | |
| 522 end | 542 end |
| 523 end | 543 end |
| 524 | 544 |
| 525 if new_user.roles then -- COMPAT w/0.12 | 545 if new_user.roles then -- COMPAT w/0.12 |
| 526 if not usermanager.set_user_roles then | 546 if not usermanager.set_user_roles then |
| 527 return 500, "feature-not-implemented" | 547 return nil, "feature-not-implemented"; |
| 528 end | 548 end |
| 529 | 549 |
| 530 local backend_roles = {}; | 550 local backend_roles = {}; |
| 531 for _, role in ipairs(new_user.roles) do | 551 for _, role in ipairs(new_user.roles) do |
| 532 backend_roles[role] = true; | 552 backend_roles[role] = true; |
| 533 end | 553 end |
| 534 local user_jid = username.."@"..module.host; | 554 local user_jid = username.."@"..module.host; |
| 535 if not usermanager.set_user_roles(username, module.host, backend_roles) then | 555 local role, role_err = usermanager.set_user_roles(username, module.host, backend_roles); |
| 536 module:log("error", "failed to set roles %q for %s", backend_roles, user_jid) | 556 if not role then |
| 537 return 500 | 557 module:log("error", "failed to set roles %q for %s: %s", backend_roles, user_jid, role_err) |
| 558 return nil, role_err; | |
| 538 end | 559 end |
| 539 end | 560 end |
| 540 | 561 |
| 541 if new_user.enabled ~= nil then | 562 if new_user.enabled ~= nil then |
| 542 if not user_attribute_writers.enabled(username, new_user.enabled) then | 563 local ok, err = user_attribute_writers.enabled(username, new_user.enabled); |
| 543 return 500; | 564 if not ok then |
| 565 return nil, err; | |
| 544 end | 566 end |
| 545 end | 567 end |
| 546 | 568 |
| 547 return 200; | 569 return 200; |
| 548 end | 570 end |
| 549 | 571 |
| 550 function delete_user(event, username) --luacheck: ignore 212/event | 572 function delete_user(event, username) --luacheck: ignore 212/event |
| 551 if not usermanager.delete_user(username, module.host) then | 573 local ok, err = usermanager.delete_user(username, module.host); |
| 552 return 404; | 574 if not ok then |
| 575 return nil, err; | |
| 553 end | 576 end |
| 554 return 200; | 577 return 200; |
| 555 end | 578 end |
| 556 | 579 |
| 557 function list_groups(event) | 580 function list_groups(event) |
| 595 local group = json.decode(event.request.body); | 618 local group = json.decode(event.request.body); |
| 596 if not group then | 619 if not group then |
| 597 return 400; | 620 return 400; |
| 598 end | 621 end |
| 599 | 622 |
| 600 if not group.name then | |
| 601 module:log("warn", "Group missing name property"); | |
| 602 return 400; | |
| 603 end | |
| 604 | |
| 605 local create_muc = group.create_muc and true or false; | 623 local create_muc = group.create_muc and true or false; |
| 606 | 624 |
| 607 local group_id = mod_groups.create( | 625 local group_id, err = mod_groups.create( |
| 608 { | 626 { |
| 609 name = group.name; | 627 name = group.name; |
| 610 }, | 628 }, |
| 611 create_muc | 629 create_muc |
| 612 ); | 630 ); |
| 613 if not group_id then | 631 if not group_id then |
| 614 return 500; | 632 return nil, err; |
| 615 end | 633 end |
| 616 | 634 |
| 617 event.response.headers["Content-Type"] = json_content_type; | 635 event.response.headers["Content-Type"] = json_content_type; |
| 618 | 636 |
| 619 local info = mod_groups.get_info(group_id); | 637 local info = mod_groups.get_info(group_id); |
| 628 function update_group(event, group) --luacheck: ignore 212/event | 646 function update_group(event, group) --luacheck: ignore 212/event |
| 629 -- Add member | 647 -- Add member |
| 630 do | 648 do |
| 631 local group_id, member_name = group:match("^([^/]+)/members/([^/]+)$"); | 649 local group_id, member_name = group:match("^([^/]+)/members/([^/]+)$"); |
| 632 if group_id and member_name then | 650 if group_id and member_name then |
| 633 if not mod_groups.add_member(group_id, member_name) then | 651 local ok, err = mod_groups.add_member(group_id, member_name); |
| 634 return 500; | 652 if not ok then |
| 653 return nil, err; | |
| 635 end | 654 end |
| 636 return 204; | 655 return 204; |
| 637 end | 656 end |
| 638 end | 657 end |
| 639 | 658 |
| 640 local group_id = group:match("^([^/]+)$") | 659 local group_id = group:match("^([^/]+)$") |
| 641 if not group_id then return 404; end | 660 if not group_id then return nil, "group-not-found"; end |
| 642 | 661 |
| 643 local request = event.request; | 662 local request = event.request; |
| 644 if request.headers.content_type ~= json_content_type or (not request.body or #request.body == 0) then | 663 if request.headers.content_type ~= json_content_type or (not request.body or #request.body == 0) then |
| 645 return 400; | 664 return nil, "invalid-json"; |
| 646 end | 665 end |
| 647 | 666 |
| 648 local update = json.decode(event.request.body); | 667 local update = json.decode(event.request.body); |
| 649 if not update then | 668 if not update then |
| 650 return 400; | 669 return nil, "invalid-json"; |
| 651 end | 670 end |
| 652 | 671 |
| 653 local group_info = mod_groups.get_info(group_id); | 672 local group_info = mod_groups.get_info(group_id); |
| 654 if not group_info then | 673 if not group_info then |
| 655 return 404; | 674 return nil, "group-not-found"; |
| 656 end | 675 end |
| 657 | 676 |
| 658 if update.name then | 677 if update.name then |
| 659 group_info["name"] = update.name; | 678 group_info["name"] = update.name; |
| 660 end | 679 end |
| 661 if not mod_groups.set_info(group_id, group_info) then | 680 local ok, err = mod_groups.set_info(group_id, group_info); |
| 662 return 500; | 681 if not ok then |
| 682 return nil, err; | |
| 663 end | 683 end |
| 664 return 204; | 684 return 204; |
| 665 end | 685 end |
| 666 | 686 |
| 667 function extend_group(event, subpath) | 687 function extend_group(event, subpath) |
