Role based data access support
This commit is contained in:
parent
f0d04b8c62
commit
17839745aa
|
@ -1,8 +1,12 @@
|
||||||
package org.gcube.application.geoportal.common.model.document.accounting;
|
package org.gcube.application.geoportal.common.model.document.accounting;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -15,4 +19,19 @@ public class User {
|
||||||
@JsonProperty(USERNAME)
|
@JsonProperty(USERNAME)
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private Set<String> roles;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof User)) return false;
|
||||||
|
User user = (User) o;
|
||||||
|
return Objects.equals(getUsername(), user.getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getUsername());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package org.gcube.application.geoportal.common.model.useCaseDescriptor;
|
package org.gcube.application.geoportal.common.model.useCaseDescriptor;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
import org.gcube.application.geoportal.common.model.document.Project;
|
||||||
|
import org.gcube.application.geoportal.common.model.document.accounting.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -55,4 +58,24 @@ public class DataAccessPolicy {
|
||||||
private List<String> roles;
|
private List<String> roles;
|
||||||
@JsonProperty(ENFORCER)
|
@JsonProperty(ENFORCER)
|
||||||
private PolicyEnforcer enforcer;
|
private PolicyEnforcer enforcer;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public boolean canRead(Project p, User u){
|
||||||
|
switch(getPolicy().getRead()){
|
||||||
|
case OWN: return p.getInfo().getCreationInfo().getUser().equals(u);
|
||||||
|
case ANY: return true;
|
||||||
|
case NONE:
|
||||||
|
default : return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public boolean canWrite(Project p, User u){
|
||||||
|
switch(getPolicy().getWrite()){
|
||||||
|
case OWN: return p.getInfo().getCreationInfo().getUser().equals(u);
|
||||||
|
case ANY: return true;
|
||||||
|
case NONE:
|
||||||
|
default : return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,9 @@ import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import lombok.extern.slf4j.XSlf4j;
|
import lombok.extern.slf4j.XSlf4j;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
import org.gcube.application.geoportal.common.model.document.Project;
|
||||||
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
|
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
|
||||||
|
import org.gcube.application.geoportal.common.model.document.accounting.User;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@ -95,6 +97,19 @@ public class UseCaseDescriptor {
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public DataAccessPolicy getMatching(User u){
|
||||||
|
DataAccessPolicy defaultPolicy = null;
|
||||||
|
for (DataAccessPolicy dataAccessPolicy : dataAccessPolicies) {
|
||||||
|
if(dataAccessPolicy.getRoles()==null||dataAccessPolicy.getRoles().isEmpty())
|
||||||
|
defaultPolicy= dataAccessPolicy;
|
||||||
|
for (String r : dataAccessPolicy.getRoles())
|
||||||
|
if (u.getRoles().contains(r))
|
||||||
|
return dataAccessPolicy;
|
||||||
|
}
|
||||||
|
return defaultPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,9 +76,16 @@ public abstract class MongoManager {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Document getDocById(ObjectId id) {
|
public Document getDocById(ObjectId id,Document additionalFilter) {
|
||||||
MongoCollection<Document> coll=getCollection();
|
MongoCollection<Document> coll=getCollection();
|
||||||
return coll.find(new Document(mongoIDFieldName(),id)).first();
|
Document condition =new Document(mongoIDFieldName(),id);
|
||||||
|
if(additionalFilter!=null)
|
||||||
|
condition.putAll(additionalFilter);
|
||||||
|
return coll.find(condition).first();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Document getDocById(ObjectId id) {
|
||||||
|
return getDocById(id,null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,7 @@ import org.gcube.application.geoportal.common.model.configuration.Configuration;
|
||||||
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
|
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
|
||||||
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
|
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
|
||||||
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
|
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
|
||||||
import org.gcube.application.geoportal.service.model.internal.faults.DeletionException;
|
import org.gcube.application.geoportal.service.model.internal.faults.*;
|
||||||
import org.gcube.application.geoportal.service.model.internal.faults.InvalidLockException;
|
|
||||||
import org.gcube.application.geoportal.service.model.internal.faults.ProjectLockedException;
|
|
||||||
import org.gcube.application.geoportal.service.model.internal.faults.ProjectNotFoundException;
|
|
||||||
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
|
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -25,25 +22,25 @@ public interface MongoManagerI<T> {
|
||||||
public T registerNew(Document toRegister) throws IOException, StepException, EventException;
|
public T registerNew(Document toRegister) throws IOException, StepException, EventException;
|
||||||
|
|
||||||
// update
|
// update
|
||||||
public T update(String id,Document toSetDocument) throws IOException, StepException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
|
public T update(String id,Document toSetDocument) throws IOException, StepException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
|
|
||||||
public void delete(String id,boolean force) throws DeletionException;
|
public void delete(String id,boolean force) throws DeletionException, InvalidUserRoleException, ProjectLockedException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException;
|
||||||
|
|
||||||
// get By ID
|
// get By ID
|
||||||
|
|
||||||
public T getByID(String id) throws IOException, ProjectNotFoundException;
|
public T getByID(String id) throws IOException, ProjectNotFoundException, InvalidUserRoleException, UnauthorizedAccess;
|
||||||
|
|
||||||
// query
|
// query
|
||||||
|
|
||||||
public Iterable<Document> query(QueryRequest request);
|
public Iterable<Document> query(QueryRequest request) throws InvalidUserRoleException;
|
||||||
public Iterable<T> filter(QueryRequest request);
|
public Iterable<T> filter(QueryRequest request) throws InvalidUserRoleException;
|
||||||
|
|
||||||
public T performStep(String id, String step, Document options) throws IOException, StepException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
|
public T performStep(String id, String step, Document options) throws IOException, StepException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;
|
||||||
|
|
||||||
public T registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
|
public T registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;
|
||||||
public T deleteFileSet(String id, String destination, Boolean force) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
|
public T deleteFileSet(String id, String destination, Boolean force) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;
|
||||||
|
|
||||||
public Configuration getConfiguration()throws ConfigurationException;
|
public Configuration getConfiguration()throws ConfigurationException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,11 @@ import org.gcube.application.geoportal.common.model.document.access.Access;
|
||||||
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
|
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
|
||||||
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
|
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
|
||||||
import org.gcube.application.geoportal.common.model.document.accounting.PublicationInfo;
|
import org.gcube.application.geoportal.common.model.document.accounting.PublicationInfo;
|
||||||
|
import org.gcube.application.geoportal.common.model.document.accounting.User;
|
||||||
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFile;
|
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFile;
|
||||||
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
|
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
|
||||||
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
|
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
|
||||||
|
import org.gcube.application.geoportal.common.model.useCaseDescriptor.DataAccessPolicy;
|
||||||
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
|
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
|
||||||
import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration;
|
import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration;
|
||||||
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
|
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
|
||||||
|
@ -98,7 +100,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Project lock(String id,String op) throws ProjectNotFoundException, ProjectLockedException, JsonProcessingException {
|
protected Project lock(String id,String op) throws ProjectNotFoundException, ProjectLockedException, JsonProcessingException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
log.trace("Locking {} cause {} ",id,op);
|
log.trace("Locking {} cause {} ",id,op);
|
||||||
|
|
||||||
Lock lock = new Lock();
|
Lock lock = new Lock();
|
||||||
|
@ -133,7 +135,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
} else return Serialization.convert(obj,Project.class);
|
} else return Serialization.convert(obj,Project.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Project unlockAndUpdate(Project proj) throws InvalidLockException, ProjectNotFoundException, JsonProcessingException {
|
protected Project unlockAndUpdate(Project proj) throws InvalidLockException, ProjectNotFoundException, JsonProcessingException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
log.trace("Unlocking {} lock is {} ",proj.getId(),proj.getLock());
|
log.trace("Unlocking {} lock is {} ",proj.getId(),proj.getLock());
|
||||||
// find one and update
|
// find one and update
|
||||||
Lock oldLock = proj.getLock();
|
Lock oldLock = proj.getLock();
|
||||||
|
@ -230,16 +232,28 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
log.info("Obtained id {} ",id);
|
log.info("Obtained id {} ",id);
|
||||||
try {
|
try {
|
||||||
return getByID(id.toHexString());
|
return getByID(id.toHexString());
|
||||||
}catch (ProjectNotFoundException e){
|
}catch (ProjectNotFoundException | InvalidUserRoleException | UnauthorizedAccess e){
|
||||||
throw new WebApplicationException("Unexpected exception while registering project ",e);
|
throw new WebApplicationException("Unexpected exception while registering project ",e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Project update(String id, Document toSet) throws IOException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
|
public Project update(String id, Document toSet) throws IOException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
log.trace("Replacing {} ",toSet);
|
log.trace("Replacing {} ",toSet);
|
||||||
Project toUpdate=lock(id,"Manual update");
|
Project toUpdate=lock(id,"Manual update");
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Registering Fileset for {} [{}] , policy for {} is {} ",id,useCaseDescriptor.getId(),u,policy);
|
||||||
|
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(!policy.canWrite(toUpdate,u)) throw new UnauthorizedAccess("No edit rights on project "+id);
|
||||||
|
|
||||||
|
|
||||||
toUpdate.setTheDocument(toSet);
|
toUpdate.setTheDocument(toSet);
|
||||||
toUpdate.getLifecycleInformation().cleanState();
|
toUpdate.getLifecycleInformation().cleanState();
|
||||||
toUpdate = onUpdate(toUpdate);
|
toUpdate = onUpdate(toUpdate);
|
||||||
|
@ -258,11 +272,20 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(String id,boolean force) throws DeletionException {
|
public void delete(String id,boolean force) throws DeletionException, InvalidUserRoleException, ProjectLockedException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException {
|
||||||
log.debug("Deleting by ID {}, force {}",id,force);
|
log.debug("Deleting by ID {}, force {}",id,force);
|
||||||
try{
|
|
||||||
Project doc =lock(id,"Deletion { force : "+force+"}");
|
Project doc =lock(id,"Deletion { force : "+force+"}");
|
||||||
|
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Registering Fileset for {} [{}] , policy for {} is {} ",id,useCaseDescriptor.getId(),u,policy);
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(!policy.canWrite(doc,u)) throw new UnauthorizedAccess("No edit rights on project "+id);
|
||||||
|
|
||||||
// TODO INVOKE LIFECYCLE
|
// TODO INVOKE LIFECYCLE
|
||||||
|
|
||||||
//if(!force&&isPublished(id)) throw new Exception("Cannot delete published documents. Unpublish it or use force = true");
|
//if(!force&&isPublished(id)) throw new Exception("Cannot delete published documents. Unpublish it or use force = true");
|
||||||
|
@ -281,22 +304,58 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
// replace(asDocumentWithId(concessione), collectionName);
|
// replace(asDocumentWithId(concessione), collectionName);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}catch(Throwable t){
|
|
||||||
throw new DeletionException("Unable to delete "+id,t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Project getByID(String id) throws ProjectNotFoundException{
|
public Project getByID(String id) throws ProjectNotFoundException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
Document doc=getDocById(asId(id));
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Accessing Project {} [{}] , policy for {} is {} ",id,useCaseDescriptor.getId(),u,policy);
|
||||||
|
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles "+u.getRoles());
|
||||||
|
}
|
||||||
|
|
||||||
|
Document doc=getDocById(asId(id),
|
||||||
|
policy==null?null:policy.getEnforcer().getFilter());
|
||||||
if(doc==null) throw new ProjectNotFoundException("No document with ID "+id);
|
if(doc==null) throw new ProjectNotFoundException("No document with ID "+id);
|
||||||
return convert(doc, Project.class);
|
|
||||||
|
Project p = convert(doc, Project.class);
|
||||||
|
if(!policy.canRead(p,u)) throw new UnauthorizedAccess("No access rights on "+id);
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Document> query(QueryRequest queryRequest) {
|
public Iterable<Document> query(QueryRequest queryRequest) throws InvalidUserRoleException {
|
||||||
log.info("Querying {} ",queryRequest);
|
|
||||||
LinkedBlockingQueue queue=new LinkedBlockingQueue<Project>();
|
LinkedBlockingQueue queue=new LinkedBlockingQueue<Project>();
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Querying {} [{}] , policy for {} is {} ",queryRequest,useCaseDescriptor.getId(),u,policy);
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.NONE)) {
|
||||||
|
log.info("Read is NONE : Returning empty collection");
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
Document finalFilter=new Document();
|
||||||
|
if(queryRequest.getFilter()!=null)
|
||||||
|
finalFilter.putAll(queryRequest.getFilter());
|
||||||
|
Document enforcerFilter =policy.getEnforcer().getFilter();
|
||||||
|
if(enforcerFilter != null)
|
||||||
|
finalFilter.putAll(enforcerFilter);
|
||||||
|
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.OWN))
|
||||||
|
finalFilter.put(Project.INFO+"."+PublicationInfo.CREATION_INFO+"."+AccountingInfo.USER+"."+User.USERNAME,u.getUsername());
|
||||||
|
queryRequest.setFilter(finalFilter);
|
||||||
|
|
||||||
|
log.debug("Final filter is {}",queryRequest.getFilter());
|
||||||
|
|
||||||
queryDoc(queryRequest).forEach(
|
queryDoc(queryRequest).forEach(
|
||||||
(Consumer<? super Document>) (Document d)->{try{
|
(Consumer<? super Document>) (Document d)->{try{
|
||||||
queue.put(d);
|
queue.put(d);
|
||||||
|
@ -306,9 +365,34 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Project> filter(QueryRequest queryRequest) {
|
public Iterable<Project> filter(QueryRequest queryRequest) throws InvalidUserRoleException {
|
||||||
log.info("Searching concessione for filter {} ",queryRequest);
|
|
||||||
LinkedBlockingQueue queue=new LinkedBlockingQueue<Project>();
|
LinkedBlockingQueue queue=new LinkedBlockingQueue<Project>();
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Querying {} [{}] , policy for {} is {} ",queryRequest,useCaseDescriptor.getId(),u,policy);
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.NONE)) {
|
||||||
|
log.info("Read is NONE : Returning empty collection");
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
Document finalFilter=new Document();
|
||||||
|
if(queryRequest.getFilter()!=null)
|
||||||
|
finalFilter.putAll(queryRequest.getFilter());
|
||||||
|
Document enforcerFilter =policy.getEnforcer().getFilter();
|
||||||
|
if(enforcerFilter != null)
|
||||||
|
finalFilter.putAll(enforcerFilter);
|
||||||
|
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.OWN))
|
||||||
|
finalFilter.put(Project.INFO+"."+PublicationInfo.CREATION_INFO+"."+AccountingInfo.USER+"."+User.USERNAME,u.getUsername());
|
||||||
|
queryRequest.setFilter(finalFilter);
|
||||||
|
|
||||||
|
log.debug("Final filter is {}",queryRequest.getFilter());
|
||||||
|
|
||||||
queryDoc(queryRequest).forEach(
|
queryDoc(queryRequest).forEach(
|
||||||
(Consumer<? super Document>) (Document d)->{try{
|
(Consumer<? super Document>) (Document d)->{try{
|
||||||
queue.put(d);
|
queue.put(d);
|
||||||
|
@ -319,9 +403,21 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Project performStep(String id, String step, Document options) throws StepException, JsonProcessingException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
|
public Project performStep(String id, String step, Document options) throws StepException, JsonProcessingException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
Project document = lock(id,"Step "+step+" execution");
|
Project document = lock(id,"Step "+step+" execution");
|
||||||
try{
|
try{
|
||||||
|
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Registering Fileset for {} [{}] , policy for {} is {} ",id,useCaseDescriptor.getId(),u,policy);
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(!policy.canWrite(document,u)) throw new UnauthorizedAccess("No edit rights on project "+id);
|
||||||
|
|
||||||
|
|
||||||
document.getLifecycleInformation().cleanState();
|
document.getLifecycleInformation().cleanState();
|
||||||
document = step(document, step, options);
|
document = step(document, step, options);
|
||||||
} catch(Throwable t){
|
} catch(Throwable t){
|
||||||
|
@ -356,13 +452,27 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Project registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
|
public Project registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
log.info("Registering Fileset for {} [useCaseDescriptor ID {}], Request is {} ",id, useCaseDescriptor.getId(),request);
|
log.info("Registering Fileset for {} [useCaseDescriptor ID {}], Request is {} ",id, useCaseDescriptor.getId(),request);
|
||||||
|
|
||||||
List<TempFile> files=request.getStreams();
|
List<TempFile> files=request.getStreams();
|
||||||
Document attributes =request.getAttributes();
|
Document attributes =request.getAttributes();
|
||||||
Project doc=lock(id,"Register Fileset");
|
Project doc=lock(id,"Register Fileset");
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Checking user rights on proj
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Registering Fileset for {} [{}] , policy for {} is {} ",id,useCaseDescriptor.getId(),u,policy);
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(!policy.canWrite(doc,u)) throw new UnauthorizedAccess("No edit rights on project "+id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
doc.getLifecycleInformation().cleanState();
|
doc.getLifecycleInformation().cleanState();
|
||||||
doc.getLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.OK);
|
doc.getLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.OK);
|
||||||
|
|
||||||
|
@ -448,12 +558,25 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Project deleteFileSet(String id, String path, Boolean force) throws ConfigurationException, StorageHubException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
|
public Project deleteFileSet(String id, String path, Boolean force) throws ConfigurationException, StorageHubException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess {
|
||||||
log.info("Deleting Fileset for {} [useCaseDescriptor ID {}], at {} [force {} ]",id, useCaseDescriptor.getId(),path,force);
|
log.info("Deleting Fileset for {} [useCaseDescriptor ID {}], at {} [force {} ]",id, useCaseDescriptor.getId(),path,force);
|
||||||
|
|
||||||
Project doc = lock(id,"Fileset Deletion");
|
Project doc = lock(id,"Fileset Deletion");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
User u = UserUtils.getCurrent().asInfo().getUser();
|
||||||
|
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
|
||||||
|
log.info("Registering Fileset for {} [{}] , policy for {} is {} ",id,useCaseDescriptor.getId(),u,policy);
|
||||||
|
// NB cannot check ownership on returned values, must specify filter
|
||||||
|
if(policy == null) {
|
||||||
|
log.warn("No policy found for {}. Returning empty ", u);
|
||||||
|
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
|
||||||
|
}
|
||||||
|
if(!policy.canWrite(doc,u)) throw new UnauthorizedAccess("No edit rights on project "+id);
|
||||||
|
|
||||||
|
|
||||||
doc.getLifecycleInformation().cleanState();
|
doc.getLifecycleInformation().cleanState();
|
||||||
doc.getLifecycleInformation().cleanState().setLastOperationStatus(LifecycleInformation.Status.OK);
|
doc.getLifecycleInformation().cleanState().setLastOperationStatus(LifecycleInformation.Status.OK);
|
||||||
|
|
||||||
|
@ -530,6 +653,8 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
|
||||||
try{
|
try{
|
||||||
log.info("[UseCaseDescriptor {}] Invoking Step {} on {}" , useCaseDescriptor.getId(),step,getManager().getDescriptor());
|
log.info("[UseCaseDescriptor {}] Invoking Step {} on {}" , useCaseDescriptor.getId(),step,getManager().getDescriptor());
|
||||||
AccountingInfo user= UserUtils.getCurrent().asInfo();
|
AccountingInfo user= UserUtils.getCurrent().asInfo();
|
||||||
|
|
||||||
|
|
||||||
StepExecutionRequest request=new StepExecutionRequest(useCaseDescriptor,user.getUser(),user.getContext(),theDocument,step);
|
StepExecutionRequest request=new StepExecutionRequest(useCaseDescriptor,user.getUser(),user.getContext(),theDocument,step);
|
||||||
|
|
||||||
log.debug("Requesting Step Execution {}",request);
|
log.debug("Requesting Step Execution {}",request);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.gcube.application.geoportal.service.model.internal.faults;
|
||||||
|
|
||||||
|
public class InvalidUserRoleException extends Exception {
|
||||||
|
|
||||||
|
public InvalidUserRoleException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidUserRoleException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidUserRoleException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidUserRoleException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidUserRoleException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.gcube.application.geoportal.service.model.internal.faults;
|
||||||
|
|
||||||
|
public class UnauthorizedAccess extends Exception {
|
||||||
|
|
||||||
|
public UnauthorizedAccess() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnauthorizedAccess(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnauthorizedAccess(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnauthorizedAccess(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnauthorizedAccess(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,9 @@ import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||||
import org.gcube.common.scope.api.ScopeProvider;
|
import org.gcube.common.scope.api.ScopeProvider;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class UserUtils {
|
public class UserUtils {
|
||||||
|
@ -29,7 +32,11 @@ public class UserUtils {
|
||||||
}catch(Throwable e) {
|
}catch(Throwable e) {
|
||||||
log.warn("Unable to get client info ",e);
|
log.warn("Unable to get client info ",e);
|
||||||
}
|
}
|
||||||
AuthenticatedUser toReturn = new AuthenticatedUser(client, AccessTokenProvider.instance.get(),SecurityTokenProvider.instance.get(),context);
|
|
||||||
|
//TODO Actually get ROLES
|
||||||
|
Set<String> roles = new HashSet<>();
|
||||||
|
AuthenticatedUser toReturn =
|
||||||
|
new AuthenticatedUser(client,roles, AccessTokenProvider.instance.get(),SecurityTokenProvider.instance.get(),context);
|
||||||
|
|
||||||
log.info("Current User is {} ",toReturn);
|
log.info("Current User is {} ",toReturn);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
|
@ -40,6 +47,9 @@ public class UserUtils {
|
||||||
@Getter
|
@Getter
|
||||||
public static class AuthenticatedUser {
|
public static class AuthenticatedUser {
|
||||||
private ClientInfo user;
|
private ClientInfo user;
|
||||||
|
|
||||||
|
private Set<String> roles;
|
||||||
|
|
||||||
private String uma_token;
|
private String uma_token;
|
||||||
|
|
||||||
private String gcube_token;
|
private String gcube_token;
|
||||||
|
@ -57,6 +67,9 @@ public class UserUtils {
|
||||||
builder.append(", gcube_token=");
|
builder.append(", gcube_token=");
|
||||||
builder.append(gcube_token==null?gcube_token:"***");
|
builder.append(gcube_token==null?gcube_token:"***");
|
||||||
|
|
||||||
|
builder.append(", roles=");
|
||||||
|
builder.append(roles);
|
||||||
|
|
||||||
builder.append(", context=");
|
builder.append(", context=");
|
||||||
builder.append(context);
|
builder.append(context);
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
|
@ -68,9 +81,11 @@ public class UserUtils {
|
||||||
User user = new User();
|
User user = new User();
|
||||||
try{
|
try{
|
||||||
user.setUsername(this.getUser().getId());
|
user.setUsername(this.getUser().getId());
|
||||||
|
user.setRoles(roles);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
log.warn("Unable to determine user id, using FAKE");
|
log.warn("Unable to determine user id, using FAKE");
|
||||||
user.setUsername("FAKE");
|
user.setUsername("FAKE");
|
||||||
|
user.setRoles(Collections.EMPTY_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.setUser(user);
|
info.setUser(user);
|
||||||
|
|
Loading…
Reference in New Issue