Skip to content

Commit

Permalink
Ongoing work on #455 - making sure API is secure
Browse files Browse the repository at this point in the history
  • Loading branch information
michbarsinai committed Oct 21, 2014
1 parent 31acaaa commit df7b30b
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 59 deletions.
13 changes: 8 additions & 5 deletions scripts/api/setup-users.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ SERVER=http://localhost:8080/api
echo Setting up users on $SERVER
echo ==============================================

peteResp=$(curl -s -H "Content-type:application/json" -X POST -d @data/userPete.json "$SERVER/users?password=pete")
curl -X PUT $SERVER/s/settings/BuiltinUsers.KEY/burrito


peteResp=$(curl -s -H "Content-type:application/json" -X POST -d @data/userPete.json "$SERVER/users?password=pete&key=burrito")
echo $peteResp

umaResp=$(curl -s -H "Content-type:application/json" -X POST -d @data/userUma.json "$SERVER/users?password=uma")
umaResp=$(curl -s -H "Content-type:application/json" -X POST -d @data/userUma.json "$SERVER/users?password=uma&key=burrito")
echo $umaResp

curl -s -H "Content-type:application/json" -X POST -d @data/userGabbi.json "$SERVER/users?password=gabbi"
curl -s -H "Content-type:application/json" -X POST -d @data/userGabbi.json "$SERVER/users?password=gabbi&key=burrito"
echo

curl -s -H "Content-type:application/json" -X POST -d @data/userCathy.json "$SERVER/users?password=cathy"
curl -s -H "Content-type:application/json" -X POST -d @data/userCathy.json "$SERVER/users?password=cathy&key=burrito"
echo

curl -s -H "Content-type:application/json" -X POST -d @data/userNick.json "$SERVER/users?password=nick"
curl -s -H "Content-type:application/json" -X POST -d @data/userNick.json "$SERVER/users?password=nick&key=burrito"
echo

command -v jq >/dev/null 2>&1 || { echo >&2 "jq required, but it's not installed. On mac, use brew (http://brew.sh) to install it. Aborting."; exit 1; }
Expand Down
45 changes: 25 additions & 20 deletions src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,16 @@ protected DvObject findDvo( Long id ) {
.getSingleResult();
}

/**
* Tries to find a DvObject. If the passed id can be interpreted as a number,
* it tries to get the DvObject by its id. Else, it tries to get a {@link Dataverse}
* with that alias. If that fails, tries to get a {@link Dataset} with that global id.
* @param id a value identifying the DvObject, either numeric of textual.
* @return A DvObject, or {@code null}
*/
protected DvObject findDvo( String id ) {
if ( isNumeric(id) ) {
return em.createNamedQuery("DvObject.findById", DvObject.class)
.setParameter("id", Long.valueOf(id))
.getSingleResult();
return findDvo( Long.valueOf(id)) ;
} else {
Dataverse d = dataverseSvc.findByAlias(id);
return ( d == null ) ?
Expand All @@ -144,6 +149,22 @@ protected MetadataBlock findMetadataBlock(String idtf) throws NumberFormatExcept
: metadataBlockSvc.findByName(idtf);
}

protected <T> T execCommand( Command<T> com, String messageSeed ) throws WrappedResponse {
try {
return engineSvc.submit(com);

} catch (IllegalCommandException ex) {
throw new WrappedResponse( errorResponse( Response.Status.FORBIDDEN, messageSeed + ": Not Allowed (" + ex.getMessage() + ")" ));

} catch (PermissionException ex) {
throw new WrappedResponse(errorResponse(Response.Status.UNAUTHORIZED, messageSeed + " unauthorized."));

} catch (CommandException ex) {
Logger.getLogger(AbstractApiBean.class.getName()).log(Level.SEVERE, "Error while " + messageSeed, ex);
throw new WrappedResponse(errorResponse(Status.INTERNAL_SERVER_ERROR, messageSeed + " failed: " + ex.getMessage()));
}
}

protected Response okResponse( JsonArrayBuilder bld ) {
return Response.ok( Json.createObjectBuilder()
.add("status", "OK")
Expand Down Expand Up @@ -183,22 +204,6 @@ protected Response okResponse( String msg ) {
.build();
}

protected <T> T execCommand( Command<T> com, String messageSeed ) throws WrappedResponse {
try {
return engineSvc.submit(com);

} catch (IllegalCommandException ex) {
throw new WrappedResponse( errorResponse( Response.Status.FORBIDDEN, messageSeed + ": Not Allowed (" + ex.getMessage() + ")" ));

} catch (PermissionException ex) {
throw new WrappedResponse(errorResponse(Response.Status.UNAUTHORIZED, messageSeed + " unauthorized."));

} catch (CommandException ex) {
Logger.getLogger(AbstractApiBean.class.getName()).log(Level.SEVERE, "Error while " + messageSeed, ex);
throw new WrappedResponse(errorResponse(Status.INTERNAL_SERVER_ERROR, messageSeed + " failed: " + ex.getMessage()));
}
}

/**
* Returns an OK response (HTTP 200, status:OK) with the passed value
* in the data field.
Expand Down Expand Up @@ -233,7 +238,7 @@ protected Response notFound( String msg ) {
}

protected Response badApiKey( String apiKey ) {
return errorResponse(Status.UNAUTHORIZED, "Bad api key '" + apiKey +"'");
return errorResponse(Status.UNAUTHORIZED, (apiKey != null ) ? "Bad api key '" + apiKey +"'" : "Please provide a key query parameter (?key=XXX)");
}

protected Response permissionError( PermissionException pe ) {
Expand Down
18 changes: 0 additions & 18 deletions src/main/java/edu/harvard/iq/dataverse/api/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,6 @@ public Response deleteSetting( @PathParam("name") String name ) {
return okResponse("Setting " + name + " deleted.");
}

@Path("setup")
@POST
public Response setup() {
settingsSvc.setValueForKey( SettingsServiceBean.Key.AllowSignUp, "1" );
settingsSvc.setValueForKey( SettingsServiceBean.Key.SignUpUrl, "builtin/signup.xhtml" );
return okResponse("setup done");
}

@Path("test")
@GET
public Response test() {
JsonObjectBuilder bld = jsonObjectBuilder();
for ( Setting s : settingsSvc.listAll() ) {
bld.add(s.getName(), settingsSvc.get(s.getName()));
}
return okResponse(bld);
}

@Path("authenticationProviderFactories")
@GET
public Response listAuthProviderFactories() {
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/edu/harvard/iq/dataverse/api/BuiltinUsers.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,20 @@
public class BuiltinUsers extends AbstractApiBean {
private static final Logger logger = Logger.getLogger(BuiltinUsers.class.getName());

private static final String API_KEY_IN_SETTINGS = "BuiltinUsers.KEY";

@EJB
protected BuiltinUserServiceBean builtinUserSvc;

@GET
public Response list() {
public Response list(@QueryParam("key") String key ) {
String expectedKey = settingsSvc.get( API_KEY_IN_SETTINGS );
if ( expectedKey==null ) {
return errorResponse(Status.SERVICE_UNAVAILABLE, "Dataverse config issue: No API key defined for built in user management");
}
if ( ! expectedKey.equals(key) ) {
return badApiKey(key);
}
JsonArrayBuilder bld = Json.createArrayBuilder();

for ( BuiltinUser u : builtinUserSvc.findAll() ) {
Expand All @@ -44,7 +53,14 @@ public Response list() {
}

@POST
public Response save( BuiltinUser user, @QueryParam("password") String password ) {
public Response save( BuiltinUser user, @QueryParam("password") String password, @QueryParam("key") String key ) {
String expectedKey = settingsSvc.get( API_KEY_IN_SETTINGS );
if ( expectedKey==null ) {
return errorResponse(Status.SERVICE_UNAVAILABLE, "Dataverse config issue: No API key defined for built in user management");
}
if ( ! expectedKey.equals(key) ) {
return badApiKey(key);
}
try {
if ( password != null ) {
user.setEncryptedPassword(builtinUserSvc.encryptPassword(password));
Expand Down
13 changes: 5 additions & 8 deletions src/main/java/edu/harvard/iq/dataverse/api/DataTagsAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ public class DataTagsAPI extends AbstractApiBean {
DataTagsContainer container;


/**
* send GET request to tagging server API for URL for user
* @return the URL at which the interview waits.
*/
public String requestInterview() {
// send GET request to tagging server API for URL for user
Client client = ClientBuilder.newClient();
WebTarget endpoint = client.target(TAGGING_SERVER_ENDPOINT);
//.path("{repositoryName}").path("{callbackURL}");
Expand Down Expand Up @@ -80,13 +83,7 @@ public Response receiveTags(JsonObject tags, @PathParam("uniqueCacheId") String
CACHE.put(uniqueCacheId, container);

// return an OK message with the redirect URL for the user to return to Dataverse through postBackTo or unacceptableDataset in DataTags
return okResponse( USER_REDIRECT_URL);
}


@GET
public String test() {
return "Working";
return okResponse( USER_REDIRECT_URL );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
query = "SELECT u FROM BuiltinUser u ORDER BY u.lastName"),
@NamedQuery( name="BuiltinUser.findByUserName",
query = "SELECT u FROM BuiltinUser u WHERE u.userName=:userName"),
@NamedQuery( name="BuiltinUser.findByEmail",
query = "SELECT o FROM BuiltinUser o WHERE o.email = :email"),
@NamedQuery( name="BuiltinUser.listByUserNameLike",
query = "SELECT u FROM BuiltinUser u WHERE u.userName LIKE :userNameLike")
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,26 @@ public BuiltinUser findByUserName(String userName) {
}

public List<BuiltinUser> listByUsernamePart ( String part ) {
return em.createNamedQuery("DataverseUser.listByUserNameLike", BuiltinUser.class)
return em.createNamedQuery("BuiltinUser.listByUserNameLike", BuiltinUser.class)
.setParameter("userNameLike", "%" + part + "%")
.getResultList();
}

/**
* @param email email of the user.
* @return A {@link BuiltinUser} or null if not found
*/
public BuiltinUser findByEmail(String email) {
TypedQuery<BuiltinUser> typedQuery = em.createQuery("SELECT OBJECT(o) FROM BuiltinUser o WHERE o.email = :email", BuiltinUser.class);
typedQuery.setParameter("email", email);
try {
BuiltinUser builtinUser = typedQuery.getSingleResult();
return builtinUser;
return em.createNamedQuery("BuiltinUser.findByEmail", BuiltinUser.class)
.setParameter("email", email)
.getSingleResult();
} catch (NoResultException | NonUniqueResultException ex) {
return null;
}
}

public List<BuiltinUser> findAll() {
return em.createNamedQuery("DataverseUser.findAll", BuiltinUser.class).getResultList();
return em.createNamedQuery("BuiltinUser.findAll", BuiltinUser.class).getResultList();
}
}

0 comments on commit df7b30b

Please sign in to comment.