Commit ae09b2a8 authored by Maxym Borodenko's avatar Maxym Borodenko
Browse files

WIP

parent ee936f93
......@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
......@@ -52,16 +53,19 @@ import javax.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import org.genesys.blocks.util.CurrentApplicationContext;
import org.gringlobal.api.InvalidApiUsageException;
import org.gringlobal.application.config.GGCESecurityConfig;
import org.gringlobal.compatibility.service.DataviewService;
import org.gringlobal.component.elastic.ElasticJPAListener;
import org.gringlobal.model.Cooperator;
import org.gringlobal.model.CooperatorOwnedModel;
import org.gringlobal.model.GGCESecurityAwareModel;
import org.gringlobal.model.QSysDataview;
import org.gringlobal.model.QSysDataviewField;
import org.gringlobal.model.QSysDataviewFieldLang;
import org.gringlobal.model.QSysDataviewLang;
import org.gringlobal.model.QSysTableField;
import org.gringlobal.model.QSysTableFieldLang;
import org.gringlobal.model.Site;
import org.gringlobal.model.SysDataview;
import org.gringlobal.model.SysDataviewField;
import org.gringlobal.model.SysDataviewFieldLang;
......@@ -73,6 +77,7 @@ import org.gringlobal.model.SysTable;
import org.gringlobal.model.SysTableField;
import org.gringlobal.model.SysTableFieldLang;
import org.gringlobal.model.SysUser;
import org.gringlobal.model.community.SecurityAction;
import org.gringlobal.persistence.CooperatorRepository;
import org.gringlobal.persistence.SysDataviewRepository;
import org.gringlobal.persistence.SysTableRepository;
......@@ -88,6 +93,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
......@@ -101,6 +107,7 @@ import org.springframework.dao.DataAccessException;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
......@@ -229,6 +236,10 @@ public class DataviewServiceImpl implements InitializingBean, DataviewService {
@Value("${dataview.max.rows}")
private int maxRowsLimit;
@Autowired
@Qualifier("ggceSec")
private GGCESecurityConfig.GgceSec ggceSec;
@Override
public void afterPropertiesSet() throws Exception {
xmlOutputter = new XMLOutputter(Format.getCompactFormat());
......@@ -925,7 +936,7 @@ public class DataviewServiceImpl implements InitializingBean, DataviewService {
continue;
}
LOG.warn("Deleting {}", existingEntity);
removeEntity(existingEntity);
checkPermissionAndDo("DELETE", existingEntity, this::removeEntity);
final Element source = befores.get(deletePk);
describeDelete(source, deletePk);
......@@ -948,7 +959,7 @@ public class DataviewServiceImpl implements InitializingBean, DataviewService {
applyXml(existingEntity, xmlDiff(befores.get(update.getKey()), updateXml), dataview);
updateCreatorInfo(existingEntity);
applyDefaults(existingEntity);
persistEntity(existingEntity);
checkPermissionAndDo("WRITE", existingEntity, this::persistEntity);
describeUpdate(updateXml, update.getKey());
insertsAndUpdates.add(updateXml);
returnPks.add(update.getKey());
......@@ -968,7 +979,7 @@ public class DataviewServiceImpl implements InitializingBean, DataviewService {
targetEntity.primaryKey.set(newEntity, null);
addCreatorInfo(newEntity);
applyDefaults(newEntity);
persistEntity(newEntity);
checkPermissionAndDo("CREATE", newEntity, this::persistEntity);
final Object newPk = targetEntity.primaryKey.get(newEntity);
LOG.debug("Persisted new {} with id={}", targetEntity.target, newPk);
......@@ -1004,7 +1015,7 @@ public class DataviewServiceImpl implements InitializingBean, DataviewService {
entityManager.remove(existingEntity);
if (elasticsearchListener != null) {
elasticsearchListener.scheduleReindexing(existingEntity);
}
}
} else {
repo.delete(existingEntity);
}
......@@ -1024,6 +1035,16 @@ public class DataviewServiceImpl implements InitializingBean, DataviewService {
}
}
private <T> void checkPermissionAndDo(Object permission, T entity, Consumer<T> consumer) {
if (GGCESecurityAwareModel.class.isAssignableFrom(entity.getClass())) {
Site site = ((GGCESecurityAwareModel) entity).aclSite();
SecurityAction securityAction = ((GGCESecurityAwareModel) entity).requiredSecurityAction();
if (!ggceSec.actionAllowed(securityAction.name(), permission, site))
throw new AccessDeniedException("Access is denied");
}
consumer.accept(entity);
}
private void applyDefaults(final Object targetEntity) {
final Class<? extends Object> clazz = targetEntity.getClass();
final SysTable sysTable = getSysTable(clazz);
......
......@@ -50,6 +50,7 @@ import org.gringlobal.custom.elasticsearch.SearchField;
import org.gringlobal.custom.validation.javax.CodeValueField;
import org.gringlobal.custom.validation.javax.OneLine;
import org.gringlobal.model.community.IWebVisible;
import org.gringlobal.model.community.SecurityAction;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
......@@ -67,7 +68,8 @@ import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@Document(indexName = "accession")
@BoostedFields({ "accessionNumber", "accessionNumberPart2", "taxonomySpecies.name", "names.plantName", "accessionSources.geography.countryCode" })
@JsonIdentityInfo(scope = Accession.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Accession extends CooperatorOwnedModel implements IWebVisible, Copyable<Accession>, ElasticLoader, ElasticTrigger {
public class Accession extends CooperatorOwnedModel implements IWebVisible, Copyable<Accession>, ElasticLoader, ElasticTrigger,
GGCESecurityAwareModel {
@Id
@JsonProperty
......@@ -493,4 +495,14 @@ public class Accession extends CooperatorOwnedModel implements IWebVisible, Copy
public Object[] reindexedEntities() {
return this.inventories == null ? null : this.inventories.toArray();
}
@Override
public Site aclSite() {
return this.site;
}
@Override
public SecurityAction requiredSecurityAction() {
return SecurityAction.PassportData;
}
}
/*
* Copyright 2021 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.model;
import org.gringlobal.model.community.SecurityAction;
/**
* Interface label for entities that require GGCE site-based security.
*/
public interface GGCESecurityAwareModel {
Site aclSite();
SecurityAction requiredSecurityAction();
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment