use of edu.harvard.iq.dataverse.actionlogging.ActionLogRecord in project dataverse by IQSS.
the class EjbDataverseEngine method submit.
public <R> R submit(Command<R> aCommand) throws CommandException {
final ActionLogRecord logRec = new ActionLogRecord(ActionLogRecord.ActionType.Command, aCommand.getClass().getCanonicalName());
try {
logRec.setUserIdentifier(aCommand.getRequest().getUser().getIdentifier());
// Check permissions - or throw an exception
Map<String, ? extends Set<Permission>> requiredMap = aCommand.getRequiredPermissions();
if (requiredMap == null) {
throw new RuntimeException("Command " + aCommand + " does not define required permissions.");
}
DataverseRequest dvReq = aCommand.getRequest();
Map<String, DvObject> affectedDvObjects = aCommand.getAffectedDvObjects();
logRec.setInfo(aCommand.describe());
for (Map.Entry<String, ? extends Set<Permission>> pair : requiredMap.entrySet()) {
String dvName = pair.getKey();
if (!affectedDvObjects.containsKey(dvName)) {
throw new RuntimeException("Command instance " + aCommand + " does not have a DvObject named '" + dvName + "'");
}
DvObject dvo = affectedDvObjects.get(dvName);
Set<Permission> granted = (dvo != null) ? permissionService.permissionsFor(dvReq, dvo) : EnumSet.allOf(Permission.class);
Set<Permission> required = requiredMap.get(dvName);
if (!granted.containsAll(required)) {
required.removeAll(granted);
logRec.setActionResult(ActionLogRecord.Result.PermissionError);
/**
* @todo Is there any harm in showing the "granted" set
* since we already show "required"? It would help people
* reason about the mismatch.
*/
throw new PermissionException("Can't execute command " + aCommand + ", because request " + aCommand.getRequest() + " is missing permissions " + required + " on Object " + dvo.accept(DvObject.NamePrinter), aCommand, required, dvo);
}
}
try {
return aCommand.execute(getContext());
} catch (EJBException ejbe) {
logRec.setActionResult(ActionLogRecord.Result.InternalError);
throw new CommandException("Command " + aCommand.toString() + " failed: " + ejbe.getMessage(), ejbe.getCausedByException(), aCommand);
}
} catch (RuntimeException re) {
logRec.setActionResult(ActionLogRecord.Result.InternalError);
logRec.setInfo(re.getMessage());
Throwable cause = re;
while (cause != null) {
if (cause instanceof ConstraintViolationException) {
StringBuilder sb = new StringBuilder();
sb.append("Unexpected bean validation constraint exception:");
ConstraintViolationException constraintViolationException = (ConstraintViolationException) cause;
for (ConstraintViolation<?> violation : constraintViolationException.getConstraintViolations()) {
sb.append(" Invalid value: <<<").append(violation.getInvalidValue()).append(">>> for ").append(violation.getPropertyPath()).append(" at ").append(violation.getLeafBean()).append(" - ").append(violation.getMessage());
}
logger.log(Level.SEVERE, sb.toString());
// set this more detailed info in action log
logRec.setInfo(sb.toString());
}
cause = cause.getCause();
}
throw re;
} finally {
if (logRec.getActionResult() == null) {
logRec.setActionResult(ActionLogRecord.Result.OK);
}
logRec.setEndTime(new java.util.Date());
logSvc.log(logRec);
}
}
use of edu.harvard.iq.dataverse.actionlogging.ActionLogRecord in project dataverse by IQSS.
the class AuthenticationServiceBean method updateProvider.
/**
* Associates the passed {@link AuthenticatedUser} with a new provider.
* @param authenticatedUser the authenticated being re-associated
* @param authenticationProviderId Id of the new provider
* @param persistentIdInProvider Id of the user in the new provider
* @return {@code true} iff the change was successful.
*/
public boolean updateProvider(AuthenticatedUser authenticatedUser, String authenticationProviderId, String persistentIdInProvider) {
try {
AuthenticatedUserLookup aul = em.createNamedQuery("AuthenticatedUserLookup.findByAuthUser", AuthenticatedUserLookup.class).setParameter("authUser", authenticatedUser).getSingleResult();
aul.setAuthenticationProviderId(authenticationProviderId);
aul.setPersistentUserId(persistentIdInProvider);
actionLogSvc.log(new ActionLogRecord(ActionLogRecord.ActionType.Auth, authenticatedUser.getIdentifier() + " now associated with provider " + authenticationProviderId + " id: " + persistentIdInProvider));
return true;
} catch (NoResultException | NonUniqueResultException ex) {
logger.log(Level.WARNING, "Error converting user " + authenticatedUser.getUserIdentifier() + ": " + ex.getMessage(), ex);
return false;
}
}
use of edu.harvard.iq.dataverse.actionlogging.ActionLogRecord in project dataverse by IQSS.
the class AuthenticationServiceBean method generateApiTokenForUser.
// A method for generating a new API token;
// TODO: this is a simple, one-size-fits-all solution; we'll need
// to expand this system, to be able to generate tokens with different
// lifecycles/valid for specific actions only, etc.
// -- L.A. 4.0 beta12
public ApiToken generateApiTokenForUser(AuthenticatedUser au) {
if (au == null) {
return null;
}
ApiToken apiToken = new ApiToken();
apiToken.setTokenString(java.util.UUID.randomUUID().toString());
apiToken.setAuthenticatedUser(au);
Calendar c = Calendar.getInstance();
apiToken.setCreateTime(new Timestamp(c.getTimeInMillis()));
c.roll(Calendar.YEAR, 1);
apiToken.setExpireTime(new Timestamp(c.getTimeInMillis()));
save(apiToken);
actionLogSvc.log(new ActionLogRecord(ActionLogRecord.ActionType.Auth, "generateApiToken").setInfo("user:" + au.getIdentifier() + " token:" + apiToken.getTokenString()));
return apiToken;
}
use of edu.harvard.iq.dataverse.actionlogging.ActionLogRecord in project dataverse by IQSS.
the class AuthenticationServiceBean method createAuthenticatedUser.
/**
* Creates an authenticated user based on the passed
* {@code userDisplayInfo}, a lookup entry for them based
* UserIdentifier.getLookupStringPerAuthProvider (within the supplied
* authentication provider), and internal user identifier (used for role
* assignments, etc.) based on UserIdentifier.getInternalUserIdentifer.
*
* @param userRecordId
* @param proposedAuthenticatedUserIdentifier
* @param userDisplayInfo
* @param generateUniqueIdentifier if {@code true}, create a new, unique user identifier for the created user, if the suggested one exists.
* @return the newly created user, or {@code null} if the proposed identifier exists and {@code generateUniqueIdentifier} was {@code false}.
* @throws EJBException which may wrap an ConstraintViolationException if the proposed user does not pass bean validation.
*/
public AuthenticatedUser createAuthenticatedUser(UserRecordIdentifier userRecordId, String proposedAuthenticatedUserIdentifier, AuthenticatedUserDisplayInfo userDisplayInfo, boolean generateUniqueIdentifier) {
AuthenticatedUser authenticatedUser = new AuthenticatedUser();
// set account creation time & initial login time (same timestamp)
authenticatedUser.setCreatedTime(new Timestamp(new Date().getTime()));
authenticatedUser.setLastLoginTime(authenticatedUser.getCreatedTime());
authenticatedUser.applyDisplayInfo(userDisplayInfo);
// we have no desire for leading or trailing whitespace in identifiers
if (proposedAuthenticatedUserIdentifier != null) {
proposedAuthenticatedUserIdentifier = proposedAuthenticatedUserIdentifier.trim();
}
// we now select a username for the generated AuthenticatedUser, or give up
String internalUserIdentifer = proposedAuthenticatedUserIdentifier;
// TODO should lock table authenticated users for write here
if (identifierExists(internalUserIdentifer)) {
if (!generateUniqueIdentifier) {
return null;
}
int i = 1;
String identifier = internalUserIdentifer + i;
while (identifierExists(identifier)) {
i += 1;
}
authenticatedUser.setUserIdentifier(identifier);
} else {
authenticatedUser.setUserIdentifier(internalUserIdentifer);
}
authenticatedUser = save(authenticatedUser);
// TODO should unlock table authenticated users for write here
AuthenticatedUserLookup auusLookup = userRecordId.createAuthenticatedUserLookup(authenticatedUser);
em.persist(auusLookup);
authenticatedUser.setAuthenticatedUserLookup(auusLookup);
if (ShibAuthenticationProvider.PROVIDER_ID.equals(auusLookup.getAuthenticationProviderId())) {
Timestamp emailConfirmedNow = new Timestamp(new Date().getTime());
// Email addresses for Shib users are confirmed by the Identity Provider.
authenticatedUser.setEmailConfirmed(emailConfirmedNow);
authenticatedUser = save(authenticatedUser);
} else {
/* @todo Rather than creating a token directly here it might be
* better to do something like "startConfirmEmailProcessForNewUser". */
confirmEmailService.createToken(authenticatedUser);
}
actionLogSvc.log(new ActionLogRecord(ActionLogRecord.ActionType.Auth, "createUser").setInfo(authenticatedUser.getIdentifier()));
return authenticatedUser;
}
use of edu.harvard.iq.dataverse.actionlogging.ActionLogRecord in project dataverse by IQSS.
the class DatasetFieldServiceApi method loadDatasetFields.
@POST
@Consumes("text/tab-separated-values")
@Path("load")
public Response loadDatasetFields(File file) {
ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "loadDatasetFields");
alr.setInfo(file.getName());
BufferedReader br = null;
String line;
String splitBy = "\t";
int lineNumber = 0;
HeaderType header = null;
JsonArrayBuilder responseArr = Json.createArrayBuilder();
try {
br = new BufferedReader(new FileReader("/" + file));
while ((line = br.readLine()) != null) {
lineNumber++;
String[] values = line.split(splitBy);
if (values[0].startsWith("#")) {
// Header row
switch(values[0]) {
case "#metadataBlock":
header = HeaderType.METADATABLOCK;
break;
case "#datasetField":
header = HeaderType.DATASETFIELD;
break;
case "#controlledVocabulary":
header = HeaderType.CONTROLLEDVOCABULARY;
break;
default:
throw new IOException("Encountered unknown #header type at line lineNumber " + lineNumber);
}
} else {
switch(header) {
case METADATABLOCK:
responseArr.add(Json.createObjectBuilder().add("name", parseMetadataBlock(values)).add("type", "MetadataBlock"));
break;
case DATASETFIELD:
responseArr.add(Json.createObjectBuilder().add("name", parseDatasetField(values)).add("type", "DatasetField"));
break;
case CONTROLLEDVOCABULARY:
responseArr.add(Json.createObjectBuilder().add("name", parseControlledVocabulary(values)).add("type", "Controlled Vocabulary"));
break;
default:
throw new IOException("No #header defined in file.");
}
}
}
} catch (FileNotFoundException e) {
alr.setActionResult(ActionLogRecord.Result.BadRequest);
alr.setInfo(alr.getInfo() + "// file not found");
return error(Status.EXPECTATION_FAILED, "File not found");
} catch (Exception e) {
Logger.getLogger(DatasetFieldServiceApi.class.getName()).log(Level.WARNING, "Error parsing dataset fields:" + e.getMessage(), e);
alr.setActionResult(ActionLogRecord.Result.InternalError);
alr.setInfo(alr.getInfo() + "// " + e.getMessage());
return error(Status.INTERNAL_SERVER_ERROR, e.getMessage());
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
Logger.getLogger(DatasetFieldServiceApi.class.getName()).log(Level.WARNING, "Error closing the reader while importing Dataset Fields.");
}
}
actionLogSvc.log(alr);
}
return ok(Json.createObjectBuilder().add("added", responseArr));
}
Aggregations