comparison mod_http_oauth2/mod_http_oauth2.lua @ 5259:8fba651b10ef

mod_http_oauth2: Refactor to allow reuse of OAuth client creation
author Kim Alvefur <zash@zash.se>
date Sun, 19 Mar 2023 22:13:27 +0100
parents 9629971e307f
children e73f364b5624
comparison
equal deleted inserted replaced
5258:9629971e307f 5259:8fba651b10ef
634 software_id = { type = "string"; format = "uuid" }; 634 software_id = { type = "string"; format = "uuid" };
635 software_version = { type = "string" }; 635 software_version = { type = "string" };
636 }; 636 };
637 } 637 }
638 638
639 local function handle_register_request(event) 639 function create_client(client_metadata)
640 local request = event.request;
641 local client_metadata = json.decode(request.body);
642
643 if not schema.validate(registration_schema, client_metadata) then 640 if not schema.validate(registration_schema, client_metadata) then
644 return oauth_error("invalid_request", "Failed schema validation."); 641 return nil, oauth_error("invalid_request", "Failed schema validation.");
645 end 642 end
646 643
647 local client_uri = url.parse(client_metadata.client_uri); 644 local client_uri = url.parse(client_metadata.client_uri);
648 if not client_uri or client_uri.scheme ~= "https" then 645 if not client_uri or client_uri.scheme ~= "https" then
649 return oauth_error("invalid_request", "Missing, invalid or insecure client_uri"); 646 return nil, oauth_error("invalid_request", "Missing, invalid or insecure client_uri");
650 end 647 end
651 648
652 for _, redirect_uri in ipairs(client_metadata.redirect_uris) do 649 for _, redirect_uri in ipairs(client_metadata.redirect_uris) do
653 local components = url.parse(redirect_uri); 650 local components = url.parse(redirect_uri);
654 if not components or not components.scheme then 651 if not components or not components.scheme then
655 return oauth_error("invalid_request", "Invalid redirect URI."); 652 return nil, oauth_error("invalid_request", "Invalid redirect URI.");
656 elseif components.scheme == "http" and components.host ~= "localhost" then 653 elseif components.scheme == "http" and components.host ~= "localhost" then
657 return oauth_error("invalid_request", "Insecure redirect URI forbidden (except http://localhost)"); 654 return nil, oauth_error("invalid_request", "Insecure redirect URI forbidden (except http://localhost)");
658 elseif components.scheme == "https" and components.host ~= client_uri.host then 655 elseif components.scheme == "https" and components.host ~= client_uri.host then
659 return oauth_error("invalid_request", "Redirects must use the same hostname as client_uri"); 656 return nil, oauth_error("invalid_request", "Redirects must use the same hostname as client_uri");
660 end 657 end
661 end 658 end
662 659
663 for field, prop_schema in pairs(registration_schema.properties) do 660 for field, prop_schema in pairs(registration_schema.properties) do
664 if field ~= "client_uri" and prop_schema.format == "uri" and client_metadata[field] then 661 if field ~= "client_uri" and prop_schema.format == "uri" and client_metadata[field] then
665 local components = url.parse(client_metadata[field]); 662 local components = url.parse(client_metadata[field]);
666 if components.scheme ~= "https" then 663 if components.scheme ~= "https" then
667 return oauth_error("invalid_request", "Insecure URI forbidden"); 664 return nil, oauth_error("invalid_request", "Insecure URI forbidden");
668 end 665 end
669 if components.authority ~= client_uri.authority then 666 if components.authority ~= client_uri.authority then
670 return oauth_error("invalid_request", "Informative URIs must have the same hostname"); 667 return nil, oauth_error("invalid_request", "Informative URIs must have the same hostname");
671 end 668 end
672 end 669 end
673 end 670 end
674 671
675 -- Ensure each signed client_id JWT is unique, short ID and issued at 672 -- Ensure each signed client_id JWT is unique, short ID and issued at
687 684
688 if not registration_options.accept_expired then 685 if not registration_options.accept_expired then
689 client_metadata.client_secret_expires_at = client_metadata.client_id_issued_at + (registration_options.default_ttl or 3600); 686 client_metadata.client_secret_expires_at = client_metadata.client_id_issued_at + (registration_options.default_ttl or 3600);
690 end 687 end
691 688
689 return client_metadata;
690 end
691
692 local function handle_register_request(event)
693 local request = event.request;
694 local client_metadata, err = json.decode(request.body);
695 if err then
696 return oauth_error("invalid_request", "Invalid JSON");
697 end
698
699 local response, err = create_client(client_metadata);
700 if err then return err end
701
692 return { 702 return {
693 status_code = 201; 703 status_code = 201;
694 headers = { content_type = "application/json" }; 704 headers = { content_type = "application/json" };
695 body = json.encode(client_metadata); 705 body = json.encode(response);
696 }; 706 };
697 end 707 end
698 708
699 if not registration_key then 709 if not registration_key then
700 module:log("info", "No 'oauth2_registration_key', dynamic client registration disabled") 710 module:log("info", "No 'oauth2_registration_key', dynamic client registration disabled")