Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 25d8d39

Browse files
author
Saad Karim
committed
[FAB-7383] 1. Support identities REST API
This change implements the different REST API call to the identity endpoint on the fabric-ca server. Change-Id: I2204c91c89a98765b41238157ac30ea596f479eb Signed-off-by: Saad Karim <skarim@us.ibm.com>
1 parent ee34177 commit 25d8d39

File tree

9 files changed

+1096
-24
lines changed

9 files changed

+1096
-24
lines changed

src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java

Lines changed: 262 additions & 20 deletions
Large diffs are not rendered by default.
Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
/*
2+
*
3+
* Copyright 2016,2017,2018 DTCC, Fujitsu Australia Software Technology, IBM - All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package org.hyperledger.fabric_ca.sdk;
18+
19+
import java.io.PrintWriter;
20+
import java.io.StringWriter;
21+
import java.util.ArrayList;
22+
import java.util.Collection;
23+
24+
import javax.json.Json;
25+
import javax.json.JsonArray;
26+
import javax.json.JsonArrayBuilder;
27+
import javax.json.JsonObject;
28+
import javax.json.JsonObjectBuilder;
29+
import javax.json.JsonWriter;
30+
31+
import org.apache.commons.logging.Log;
32+
import org.apache.commons.logging.LogFactory;
33+
import org.hyperledger.fabric.sdk.User;
34+
import org.hyperledger.fabric.sdk.helper.Utils;
35+
import org.hyperledger.fabric_ca.sdk.exception.HTTPException;
36+
import org.hyperledger.fabric_ca.sdk.exception.IdentityException;
37+
import org.hyperledger.fabric_ca.sdk.exception.InvalidArgumentException;
38+
39+
import static java.lang.String.format;
40+
// Hyperledger Fabric CA Identity information
41+
42+
public class HFCAIdentity {
43+
44+
// The enrollment ID of the user
45+
private final String enrollmentID;
46+
// Type of identity
47+
private String type = "user";
48+
// Optional secret
49+
private String secret;
50+
// Maximum number of enrollments with the secret
51+
private Integer maxEnrollments = null;
52+
// Affiliation for a user
53+
private String affiliation;
54+
// Array of attribute names and values
55+
private Collection<Attribute> attrs = new ArrayList<Attribute>();
56+
57+
private HFCAClient client;
58+
private int statusCode;
59+
60+
static final String HFCA_IDENTITY = HFCAClient.HFCA_CONTEXT_ROOT + "identities";
61+
private static final Log logger = LogFactory.getLog(HFCAClient.class);
62+
63+
HFCAIdentity(String enrollmentID, HFCAClient client) throws InvalidArgumentException {
64+
if (Utils.isNullOrEmpty(enrollmentID)) {
65+
throw new InvalidArgumentException("EnrollmentID cannot be null or empty");
66+
}
67+
68+
if (client.getCryptoSuite() == null) {
69+
throw new InvalidArgumentException("Client's crypto primitives not set");
70+
}
71+
72+
this.enrollmentID = enrollmentID;
73+
this.client = client;
74+
}
75+
76+
HFCAIdentity(JsonObject result) {
77+
this.enrollmentID = result.getString("id");
78+
getHFCAIdentity(result);
79+
}
80+
81+
/**
82+
* The name of the identity
83+
*
84+
* @return The identity name.
85+
*/
86+
87+
public String getEnrollmentId() {
88+
return enrollmentID;
89+
}
90+
91+
/**
92+
* The type of the identity
93+
*
94+
* @return The identity type.
95+
*/
96+
97+
public String getType() {
98+
return type;
99+
}
100+
101+
public void setType(String type) {
102+
this.type = type;
103+
}
104+
105+
/**
106+
* The secret of the identity
107+
*
108+
* @return The identity secret.
109+
*/
110+
111+
public String getSecret() {
112+
return secret;
113+
}
114+
115+
public void setSecret(String secret) {
116+
this.secret = secret;
117+
}
118+
119+
/**
120+
* The max enrollment value of the identity
121+
*
122+
* @return The identity max enrollment.
123+
*/
124+
125+
public Integer getMaxEnrollments() {
126+
return maxEnrollments;
127+
}
128+
129+
public void setMaxEnrollments(Integer maxEnrollments) {
130+
this.maxEnrollments = maxEnrollments;
131+
}
132+
133+
/**
134+
* The affiliation of the identity
135+
*
136+
* @return The identity affiliation.
137+
*/
138+
139+
public String getAffiliation() {
140+
return affiliation;
141+
}
142+
143+
public void setAffiliation(String affiliation) {
144+
this.affiliation = affiliation;
145+
}
146+
147+
/**
148+
* The attributes of the identity
149+
*
150+
* @return The identity attributes.
151+
*/
152+
153+
public Collection<Attribute> getAttributes() {
154+
return attrs;
155+
}
156+
157+
public void setAttributes(Collection<Attribute> attributes) {
158+
this.attrs = attributes;
159+
}
160+
161+
/**
162+
* read retrieves a specific identity
163+
*
164+
* @param registrar The identity of the registrar (i.e. who is performing the registration).
165+
* @return statusCode The HTTP status code in the response
166+
* @throws IdentityException if retrieving an identity fails.
167+
* @throws InvalidArgumentException Invalid (null) argument specified
168+
*/
169+
170+
public int read(User registrar) throws IdentityException, InvalidArgumentException {
171+
if (registrar == null) {
172+
throw new InvalidArgumentException("Registrar should be a valid member");
173+
}
174+
175+
String readIdURL = "";
176+
try {
177+
readIdURL = HFCA_IDENTITY + "/" + enrollmentID;
178+
logger.debug(format("identity url: %s, registrar: %s", readIdURL, registrar.getName()));
179+
180+
String authHdr = client.getHTTPAuthCertificate(registrar.getEnrollment(), "");
181+
JsonObject result = client.httpGet(readIdURL, authHdr);
182+
183+
statusCode = result.getInt("statusCode");
184+
if (statusCode < 400) {
185+
type = result.getString("type");
186+
maxEnrollments = result.getInt("max_enrollments");
187+
affiliation = result.getString("affiliation");
188+
189+
JsonArray attributes = result.getJsonArray("attrs");
190+
Collection<Attribute> attrs = new ArrayList<Attribute>();
191+
if (attributes != null && !attributes.isEmpty()) {
192+
for (int i = 0; i < attributes.size(); i++) {
193+
JsonObject attribute = attributes.getJsonObject(i);
194+
Attribute attr = new Attribute(attribute.getString("name"), attribute.getString("value"), attribute.getBoolean("ecert", false));
195+
attrs.add(attr);
196+
}
197+
}
198+
this.attrs = attrs;
199+
200+
logger.debug(format("identity url: %s, registrar: %s done.", readIdURL, registrar));
201+
}
202+
return statusCode;
203+
} catch (HTTPException e) {
204+
String msg = format("[Code: %d] - Error while getting user '%s' from url '%s': %s", e.getStatusCode(), getEnrollmentId(), readIdURL, e.getMessage());
205+
IdentityException identityException = new IdentityException(msg, e);
206+
logger.error(msg);
207+
throw identityException;
208+
} catch (Exception e) {
209+
String msg = format("Error while getting user '%s' from url '%s': %s", enrollmentID, readIdURL, e.getMessage());
210+
IdentityException identityException = new IdentityException(msg, e);
211+
logger.error(msg);
212+
throw identityException;
213+
}
214+
215+
}
216+
217+
/**
218+
* create an identity
219+
*
220+
* @param registrar The identity of the registrar (i.e. who is performing the registration).
221+
* @return statusCode The HTTP status code in the response
222+
* @throws IdentityException if creating an identity fails.
223+
* @throws InvalidArgumentException Invalid (null) argument specified
224+
*/
225+
226+
public int create(User registrar) throws IdentityException, InvalidArgumentException {
227+
if (registrar == null) {
228+
throw new InvalidArgumentException("Registrar should be a valid member");
229+
}
230+
231+
String createURL = "";
232+
try {
233+
createURL = client.getURL(HFCA_IDENTITY);
234+
logger.debug(format("identity url: %s, registrar: %s", createURL, registrar.getName()));
235+
236+
String body = this.toJson();
237+
String authHdr = client.getHTTPAuthCertificate(registrar.getEnrollment(), body);
238+
JsonObject result = client.httpPost(createURL, body, authHdr);
239+
statusCode = result.getInt("statusCode");
240+
if (statusCode >= 400) {
241+
getHFCAIdentity(result);
242+
logger.debug(format("identity url: %s, registrar: %s done.", createURL, registrar));
243+
}
244+
return statusCode;
245+
} catch (HTTPException e) {
246+
String msg = format("[Code: %d] - Error while creating user '%s' from url '%s': %s", e.getStatusCode(), getEnrollmentId(), createURL, e.getMessage());
247+
IdentityException identityException = new IdentityException(msg, e);
248+
logger.error(msg);
249+
throw identityException;
250+
} catch (Exception e) {
251+
String msg = format("Error while creating user '%s' from url '%s': %s", getEnrollmentId(), createURL, e.getMessage());
252+
IdentityException identityException = new IdentityException(msg, e);
253+
logger.error(msg);
254+
throw identityException;
255+
}
256+
}
257+
258+
/**
259+
* modify an identity
260+
*
261+
* @param registrar The identity of the registrar (i.e. who is performing the registration).
262+
* @return statusCode The HTTP status code in the response
263+
* @throws IdentityException if adding an identity fails.
264+
* @throws InvalidArgumentException Invalid (null) argument specified
265+
*/
266+
267+
public int update(User registrar) throws IdentityException, InvalidArgumentException {
268+
if (registrar == null) {
269+
throw new InvalidArgumentException("Registrar should be a valid member");
270+
}
271+
272+
String updateURL = "";
273+
try {
274+
updateURL = client.getURL(HFCA_IDENTITY + "/" + getEnrollmentId());
275+
logger.debug(format("identity url: %s, registrar: %s", updateURL, registrar.getName()));
276+
277+
String body = this.toJson();
278+
String authHdr = client.getHTTPAuthCertificate(registrar.getEnrollment(), body);
279+
280+
JsonObject result = client.httpPut(updateURL, body, authHdr);
281+
statusCode = result.getInt("statusCode");
282+
if (statusCode < 400) {
283+
getHFCAIdentity(result);
284+
logger.debug(format("identity url: %s, registrar: %s done.", updateURL, registrar));
285+
}
286+
return statusCode;
287+
} catch (HTTPException e) {
288+
String msg = format("[Code: %d] - Error while updating user '%s' from url '%s': %s", e.getStatusCode(), getEnrollmentId(), updateURL, e.getMessage());
289+
IdentityException identityException = new IdentityException(msg, e);
290+
logger.error(msg);
291+
throw identityException;
292+
} catch (Exception e) {
293+
String msg = format("Error while updating user '%s' from url '%s': %s", getEnrollmentId(), updateURL, e.getMessage());
294+
IdentityException identityException = new IdentityException(msg, e);
295+
logger.error(msg);
296+
throw identityException;
297+
}
298+
}
299+
300+
/**
301+
* delete an identity
302+
*
303+
* @param registrar The identity of the registrar (i.e. who is performing the registration).
304+
* @return statusCode The HTTP status code in the response
305+
* @throws IdentityException if adding an identity fails.
306+
* @throws InvalidArgumentException Invalid (null) argument specified
307+
*/
308+
309+
public int delete(User registrar) throws IdentityException, InvalidArgumentException {
310+
if (registrar == null) {
311+
throw new InvalidArgumentException("Registrar should be a valid member");
312+
}
313+
314+
String deleteURL = "";
315+
try {
316+
deleteURL = client.getURL(HFCA_IDENTITY + "/" + getEnrollmentId());
317+
logger.debug(format("identity url: %s, registrar: %s", deleteURL, registrar.getName()));
318+
319+
String authHdr = client.getHTTPAuthCertificate(registrar.getEnrollment(), "");
320+
JsonObject result = client.httpDelete(deleteURL, authHdr);
321+
statusCode = result.getInt("statusCode");
322+
if (statusCode < 400) {
323+
getHFCAIdentity(result);
324+
logger.debug(format("identity url: %s, registrar: %s done.", deleteURL, registrar));
325+
}
326+
return statusCode;
327+
} catch (HTTPException e) {
328+
String msg = format("[Code: %d] - Error while deleting user '%s' from url '%s': %s", e.getStatusCode(), getEnrollmentId(), deleteURL, e.getMessage());
329+
IdentityException identityException = new IdentityException(msg, e);
330+
logger.error(msg);
331+
throw identityException;
332+
} catch (Exception e) {
333+
String msg = format("Error while deleting user '%s' from url '%s': %s", getEnrollmentId(), deleteURL, e.getMessage());
334+
IdentityException identityException = new IdentityException(msg, e);
335+
logger.error(msg);
336+
throw identityException;
337+
}
338+
}
339+
340+
private void getHFCAIdentity(JsonObject result) {
341+
type = result.getString("type");
342+
if (result.containsKey("secret")) {
343+
this.secret = result.getString("secret");
344+
}
345+
maxEnrollments = result.getInt("max_enrollments");
346+
affiliation = result.getString("affiliation");
347+
JsonArray attributes = result.getJsonArray("attrs");
348+
349+
Collection<Attribute> attrs = new ArrayList<Attribute>();
350+
if (attributes != null && !attributes.isEmpty()) {
351+
for (int i = 0; i < attributes.size(); i++) {
352+
JsonObject attribute = attributes.getJsonObject(i);
353+
Attribute attr = new Attribute(attribute.getString("name"), attribute.getString("value"), attribute.getBoolean("ecert", false));
354+
attrs.add(attr);
355+
}
356+
}
357+
this.attrs = attrs;
358+
}
359+
360+
// Convert the identity request to a JSON string
361+
String toJson() {
362+
StringWriter stringWriter = new StringWriter();
363+
JsonWriter jsonWriter = Json.createWriter(new PrintWriter(stringWriter));
364+
jsonWriter.writeObject(toJsonObject());
365+
jsonWriter.close();
366+
return stringWriter.toString();
367+
}
368+
369+
// Convert the identity request to a JSON object
370+
JsonObject toJsonObject() {
371+
JsonObjectBuilder ob = Json.createObjectBuilder();
372+
ob.add("id", enrollmentID);
373+
ob.add("type", type);
374+
if (null != maxEnrollments) {
375+
ob.add("max_enrollments", maxEnrollments);
376+
}
377+
if (affiliation != null) {
378+
ob.add("affiliation", affiliation);
379+
}
380+
381+
JsonArrayBuilder ab = Json.createArrayBuilder();
382+
for (Attribute attr : attrs) {
383+
ab.add(attr.toJsonObject());
384+
}
385+
ob.add("attrs", ab.build());
386+
387+
JsonObjectBuilder ob2 = Json.createObjectBuilder();
388+
ob2.add("info", ob);
389+
if (this.secret != null) {
390+
ob2.add("secret", secret);
391+
}
392+
if (client.getCAName() != null) {
393+
ob2.add(HFCAClient.FABRIC_CA_REQPROP, client.getCAName());
394+
}
395+
return ob2.build();
396+
}
397+
}

0 commit comments

Comments
 (0)