1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Text ;
5+ using System . Threading . Tasks ;
6+
7+ namespace NHB3
8+ {
9+ class Api
10+ {
11+ private string urlRoot ;
12+ private string orgId ;
13+ private string apiKey ;
14+ private string apiSecret ;
15+
16+ public string time ;
17+
18+ public Api ( string urlRoot , string orgId , string apiKey , string apiSecret )
19+ {
20+ this . urlRoot = urlRoot ;
21+ this . orgId = orgId ;
22+ this . apiKey = apiKey ;
23+ this . apiSecret = apiSecret ;
24+ }
25+
26+ private static string HashBySegments ( string key , string apiKey , string time , string nonce , string orgId , string method , string encodedPath , string query , string bodyStr )
27+ {
28+ List < string > segments = new List < string > ( ) ;
29+ segments . Add ( apiKey ) ;
30+ segments . Add ( time ) ;
31+ segments . Add ( nonce ) ;
32+ segments . Add ( null ) ;
33+ segments . Add ( orgId ) ;
34+ segments . Add ( null ) ;
35+ segments . Add ( method ) ;
36+ segments . Add ( encodedPath == null ? null : encodedPath ) ;
37+ segments . Add ( query == null ? null : query ) ;
38+
39+ if ( bodyStr != null && bodyStr . Length > 0 )
40+ {
41+ segments . Add ( bodyStr ) ;
42+ }
43+ return Api . CalcHMACSHA256Hash ( Api . JoinSegments ( segments ) , key ) ;
44+ }
45+ private static string getPath ( string url )
46+ {
47+ var arrSplit = url . Split ( '?' ) ;
48+ return arrSplit [ 0 ] ;
49+ }
50+ private static string getQuery ( string url )
51+ {
52+ var arrSplit = url . Split ( '?' ) ;
53+
54+ if ( arrSplit . Length == 1 )
55+ {
56+ return null ;
57+ }
58+ else
59+ {
60+ return arrSplit [ 1 ] ;
61+ }
62+ }
63+
64+ private static string JoinSegments ( List < string > segments )
65+ {
66+ var sb = new System . Text . StringBuilder ( ) ;
67+ bool first = true ;
68+ foreach ( var segment in segments )
69+ {
70+ if ( ! first )
71+ {
72+ sb . Append ( "\x00 " ) ;
73+ }
74+ else
75+ {
76+ first = false ;
77+ }
78+
79+ if ( segment != null )
80+ {
81+ sb . Append ( segment ) ;
82+ }
83+ }
84+ Console . Out . WriteLine ( "req: [" + sb . ToString ( ) + "]" ) ;
85+ return sb . ToString ( ) ;
86+ }
87+
88+ private static string CalcHMACSHA256Hash ( string plaintext , string salt )
89+ {
90+ string result = "" ;
91+ var enc = Encoding . Default ;
92+ byte [ ]
93+ baText2BeHashed = enc . GetBytes ( plaintext ) ,
94+ baSalt = enc . GetBytes ( salt ) ;
95+ System . Security . Cryptography . HMACSHA256 hasher = new System . Security . Cryptography . HMACSHA256 ( baSalt ) ;
96+ byte [ ] baHashedText = hasher . ComputeHash ( baText2BeHashed ) ;
97+ result = string . Join ( "" , baHashedText . ToList ( ) . Select ( b => b . ToString ( "x2" ) ) . ToArray ( ) ) ;
98+ return result ;
99+ }
100+
101+ private string srvrTime ( )
102+ {
103+ string timeResponse = this . get ( "/api/v2/time" , false ) ;
104+ ServerTime serverTimeObject = Newtonsoft . Json . JsonConvert . DeserializeObject < ServerTime > ( timeResponse ) ;
105+ time = serverTimeObject . serverTime ;
106+ return time ;
107+ }
108+
109+ public string get ( string url , bool auth )
110+ {
111+ var client = new RestSharp . RestClient ( this . urlRoot ) ;
112+ var request = new RestSharp . RestRequest ( url ) ;
113+
114+ if ( auth )
115+ {
116+ string time = this . srvrTime ( ) ;
117+ string nonce = Guid . NewGuid ( ) . ToString ( ) ;
118+ string digest = Api . HashBySegments ( this . apiSecret , this . apiKey , time , nonce , this . orgId , "GET" , getPath ( url ) , getQuery ( url ) , null ) ;
119+
120+ request . AddHeader ( "X-Time" , time ) ;
121+ request . AddHeader ( "X-Nonce" , nonce ) ;
122+ request . AddHeader ( "X-Auth" , this . apiKey + ":" + digest ) ;
123+ request . AddHeader ( "X-Organization-Id" , this . orgId ) ;
124+ }
125+
126+ var response = client . Execute ( request , RestSharp . Method . GET ) ;
127+ //Console.Out.WriteLine("res: [" + response.Content + "]");
128+ var content = response . Content ;
129+ return content ;
130+ }
131+
132+ public string post ( string url , string payload , bool requestId )
133+ {
134+ string time = this . srvrTime ( ) ;
135+ var client = new RestSharp . RestClient ( this . urlRoot ) ;
136+ var request = new RestSharp . RestRequest ( url ) ;
137+ request . AddHeader ( "Accept" , "application/json" ) ;
138+ request . AddHeader ( "Content-type" , "application/json" ) ;
139+
140+ string nonce = Guid . NewGuid ( ) . ToString ( ) ;
141+ string digest = Api . HashBySegments ( this . apiSecret , this . apiKey , time , nonce , this . orgId , "POST" , getPath ( url ) , getQuery ( url ) , payload ) ;
142+
143+ if ( payload != null )
144+ {
145+ request . AddJsonBody ( payload ) ;
146+ }
147+
148+ request . AddHeader ( "X-Time" , time ) ;
149+ request . AddHeader ( "X-Nonce" , nonce ) ;
150+ request . AddHeader ( "X-Auth" , this . apiKey + ":" + digest ) ;
151+ request . AddHeader ( "X-Organization-Id" , this . orgId ) ;
152+
153+ if ( requestId )
154+ {
155+ request . AddHeader ( "X-Request-Id" , Guid . NewGuid ( ) . ToString ( ) ) ;
156+ }
157+
158+ var response = client . Execute ( request , RestSharp . Method . POST ) ;
159+ //Console.Out.WriteLine("res: [" + response.Content + "]");
160+ var content = response . Content ;
161+ return content ;
162+ }
163+
164+ public string delete ( string url , bool requestId )
165+ {
166+ string time = this . srvrTime ( ) ;
167+ var client = new RestSharp . RestClient ( this . urlRoot ) ;
168+ var request = new RestSharp . RestRequest ( url ) ;
169+
170+ string nonce = Guid . NewGuid ( ) . ToString ( ) ;
171+ string digest = Api . HashBySegments ( this . apiSecret , this . apiKey , time , nonce , this . orgId , "DELETE" , getPath ( url ) , getQuery ( url ) , null ) ;
172+
173+ request . AddHeader ( "X-Time" , time ) ;
174+ request . AddHeader ( "X-Nonce" , nonce ) ;
175+ request . AddHeader ( "X-Auth" , this . apiKey + ":" + digest ) ;
176+ request . AddHeader ( "X-Organization-Id" , this . orgId ) ;
177+
178+ if ( requestId )
179+ {
180+ request . AddHeader ( "X-Request-Id" , Guid . NewGuid ( ) . ToString ( ) ) ;
181+ }
182+
183+ var response = client . Execute ( request , RestSharp . Method . DELETE ) ;
184+ //Console.Out.WriteLine("res: [" + response.Content + "]");
185+ var content = response . Content ;
186+ return content ;
187+ }
188+ }
189+
190+ public class ServerTime
191+ {
192+ public string serverTime { get ; set ; }
193+ }
194+ }
0 commit comments