Mercurial > prosody-modules
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") |