11package  redfish
22
33import  (
4+ 	"bytes" 
45	"context" 
56	"crypto/tls" 
67	"encoding/json" 
78	"fmt" 
9+ 	"io" 
810	"net/http" 
911	"net/url" 
1012	"reflect" 
@@ -21,6 +23,8 @@ type redfishClient struct {
2123	password    string 
2224	httpClient  * http.Client 
2325	noEscape    bool 
26+ 	token       string 
27+ 	sessionId   string 
2428}
2529
2630// ClientConfig is a set of configurations for redfishClient. 
@@ -163,8 +167,9 @@ func (c *redfishClient) newRequest(ctx context.Context, path string) (*http.Requ
163167	if  err  !=  nil  {
164168		return  nil , err 
165169	}
166- 	req .SetBasicAuth ( c . user , c .password )
170+ 	req .Header . Set ( "X-auth-token" , c .token )
167171	req .Header .Set ("Accept" , "application/json" )
172+ 
168173	req  =  req .WithContext (ctx )
169174
170175	return  req , nil 
@@ -194,3 +199,90 @@ func (c *redfishClient) follow(ctx context.Context, parsed *gabs.Container, cl C
194199		return 
195200	}
196201}
202+ 
203+ type  BasicAuthentication  struct  {
204+ 	Username  string  `json:"UserName"` 
205+ 	Password  string  `json:"Password"` 
206+ }
207+ 
208+ type  ResultAuthentication  struct  {
209+ 	Id  string  `json:"Id"` 
210+ }
211+ 
212+ func  (c  * redfishClient ) Login (ctx  context.Context ) error  {
213+ 	if  c .CheckSession (ctx ) ==  nil  {
214+ 		return  nil 
215+ 	}
216+ 
217+ 	bAuth  :=  BasicAuthentication {
218+ 		Username : c .user ,
219+ 		Password : c .password ,
220+ 	}
221+ 	jsonBody , err  :=  json .Marshal (bAuth )
222+ 	if  err  !=  nil  {
223+ 		return  fmt .Errorf ("error marshaling JSON: %s" , err )
224+ 	}
225+ 
226+ 	tr  :=  http .DefaultTransport .(* http.Transport ).Clone ()
227+ 	tr .TLSClientConfig  =  & tls.Config {
228+ 		InsecureSkipVerify : true , // For self-signed certificates 
229+ 	}
230+ 
231+ 	c .httpClient  =  & http.Client {Transport : tr , Timeout : 5  *  time .Second }
232+ 	url  :=  fmt .Sprintf ("%s/%s" , c .endpoint , "redfish/v1/SessionService/Sessions" )
233+ 	req , err  :=  http .NewRequestWithContext (ctx , "POST" , url , bytes .NewBuffer (jsonBody ))
234+ 	if  err  !=  nil  {
235+ 		return  fmt .Errorf ("error making NewRequest: %s" , err )
236+ 	}
237+ 	req .Header .Set ("Content-Type" , "application/json" )
238+ 
239+ 	resp , err  :=  c .httpClient .Do (req )
240+ 	if  err  !=  nil  {
241+ 		return  fmt .Errorf ("error accessing rest service: %s" , err )
242+ 	}
243+ 
244+ 	byteJSON , err  :=  io .ReadAll (resp .Body )
245+ 	if  err  !=  nil  {
246+ 		return  fmt .Errorf ("error reading http body: %s" , err )
247+ 	}
248+ 
249+ 	var  ses  ResultAuthentication 
250+ 	json .Unmarshal (byteJSON , & ses )
251+ 	c .sessionId  =  ses .Id 
252+ 	c .token  =  resp .Header .Get ("X-auth-token" )
253+ 
254+ 	return  nil 
255+ }
256+ 
257+ func  (c  * redfishClient ) CheckSession (ctx  context.Context ) error  {
258+ 	tr  :=  http .DefaultTransport .(* http.Transport ).Clone ()
259+ 	tr .TLSClientConfig  =  & tls.Config {
260+ 		InsecureSkipVerify : true , // For self-signed certificates 
261+ 	}
262+ 	c .httpClient  =  & http.Client {Transport : tr , Timeout : 5  *  time .Second }
263+ 
264+ 	url  :=  fmt .Sprintf ("%s/%s/%s" , c .endpoint , "redfish/v1/SessionService/Sessions" , c .sessionId )
265+ 	req , err  :=  http .NewRequestWithContext (ctx , "GET" , url , nil )
266+ 	if  err  !=  nil  {
267+ 		return  fmt .Errorf ("error making NewRequest: %s" , err )
268+ 	}
269+ 	req .Header .Set ("Content-Type" , "application/json" )
270+ 	req .Header .Set ("X-auth-token" , c .token )
271+ 
272+ 	resp , err  :=  c .httpClient .Do (req )
273+ 	if  err  !=  nil  {
274+ 		return  fmt .Errorf ("error accessing rest service: %s" , err )
275+ 	}
276+ 
277+ 	var  ses  ResultAuthentication 
278+ 	byteJSON , err  :=  io .ReadAll (resp .Body )
279+ 	if  err  !=  nil  {
280+ 		return  fmt .Errorf ("error reading http body: %s" , err )
281+ 	}
282+ 
283+ 	json .Unmarshal (byteJSON , & ses )
284+ 	if  c .sessionId  ==  ses .Id  &&  c .sessionId  !=  ""  {
285+ 		return  nil 
286+ 	}
287+ 	return  fmt .Errorf ("not exist session" )
288+ }
0 commit comments