1+ // Copyright 2025 Adobe. All rights reserved.
2+ // This file is licensed to you under the Apache License, Version 2.0 (the "License");
3+ // you may not use this file except in compliance with the License. You may obtain a copy
4+ // of the License at http://www.apache.org/licenses/LICENSE-2.0
5+ //
6+ // Unless required by applicable law or agreed to in writing, software distributed under
7+ // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
8+ // OF ANY KIND, either express or implied. See the License for the specific language
9+ // governing permissions and limitations under the License.
10+
111package ims
212
313import (
14+ "encoding/json"
415 "fmt"
516 "io"
617 "net/http"
718 "strings"
819)
920
10- // RegisterResponse contains the response from DCR registration
11- type RegisterResponse struct {
12- StatusCode int
13- Body string
14- }
15-
1621func (i Config ) validateRegisterConfig () error {
1722 switch {
1823 case i .URL == "" :
1924 return fmt .Errorf ("missing IMS base URL parameter" )
25+ case ! validateURL (i .URL ):
26+ return fmt .Errorf ("invalid IMS base URL parameter" )
2027 case i .ClientName == "" :
2128 return fmt .Errorf ("missing client name parameter" )
2229 case len (i .RedirectURIs ) == 0 :
@@ -26,48 +33,44 @@ func (i Config) validateRegisterConfig() error {
2633 }
2734}
2835
29- // Register performs Dynamic Client Registration
30- func (i Config ) Register () (RegisterResponse , error ) {
36+ // Register performs Dynamic Client Registration.
37+ func (i Config ) Register () (string , error ) {
3138 if err := i .validateRegisterConfig (); err != nil {
32- return RegisterResponse {} , fmt .Errorf ("invalid parameters for client registration: %v " , err )
39+ return "" , fmt .Errorf ("invalid parameters for client registration: %w " , err )
3340 }
3441
35- // Build redirect URIs JSON array
36- redirectURIsJSON := "["
37- for idx , uri := range i . RedirectURIs {
38- if idx > 0 {
39- redirectURIsJSON += ","
40- }
41- redirectURIsJSON += fmt .Sprintf ( `"%s"` , uri )
42+ // Build the request payload using json.Marshal for proper escaping.
43+ payload , err := json . Marshal ( map [ string ] interface {}{
44+ "client_name" : i . ClientName ,
45+ "redirect_uris" : i . RedirectURIs ,
46+ })
47+ if err != nil {
48+ return "" , fmt .Errorf ( "error building registration payload: %w" , err )
4249 }
43- redirectURIsJSON += "]"
44-
45- payload := strings .NewReader (fmt .Sprintf (`{
46- "client_name": "%s",
47- "redirect_uris": %s
48- }` , i .ClientName , redirectURIsJSON ))
4950
5051 endpoint := strings .TrimRight (i .URL , "/" ) + "/ims/register"
5152
52- req , err := http .NewRequest ("POST" , endpoint , payload )
53+ req , err := http .NewRequest ("POST" , endpoint , strings . NewReader ( string ( payload )) )
5354 if err != nil {
54- return RegisterResponse {} , fmt .Errorf ("error creating request: %v " , err )
55+ return "" , fmt .Errorf ("error creating request: %w " , err )
5556 }
5657 req .Header .Add ("content-type" , "application/json" )
5758
58- res , err := http .DefaultClient .Do (req )
59+ httpClient , err := i .httpClient ()
60+ if err != nil {
61+ return "" , fmt .Errorf ("error creating the HTTP client: %w" , err )
62+ }
63+
64+ res , err := httpClient .Do (req )
5965 if err != nil {
60- return RegisterResponse {} , fmt .Errorf ("error making registration request: %v " , err )
66+ return "" , fmt .Errorf ("error making registration request: %w " , err )
6167 }
6268 defer func () { _ = res .Body .Close () }()
6369
6470 body , err := io .ReadAll (res .Body )
6571 if err != nil {
66- return RegisterResponse {} , fmt .Errorf ("error reading response body: %v " , err )
72+ return "" , fmt .Errorf ("error reading response body: %w " , err )
6773 }
6874
69- return RegisterResponse {
70- StatusCode : res .StatusCode ,
71- Body : string (body ),
72- }, nil
75+ return string (body ), nil
7376}
0 commit comments