mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-19 08:36:21 +00:00
Updated entity manager to prep for ordered list
This commit is contained in:
parent
977e4c6576
commit
60e083a048
@ -6,7 +6,6 @@ import hirs.attestationca.service.DeviceServiceImpl;
|
||||
import hirs.attestationca.service.PolicyServiceImpl;
|
||||
import hirs.attestationca.service.ReferenceDigestValueServiceImpl;
|
||||
import hirs.attestationca.service.ReferenceManifestServiceImpl;
|
||||
import hirs.data.persist.SupplyChainValidationSummary;
|
||||
import hirs.persist.service.CertificateService;
|
||||
import hirs.persist.service.DeviceService;
|
||||
import hirs.persist.service.PolicyService;
|
||||
@ -110,35 +109,21 @@ public class PersistenceConfiguration {
|
||||
setDbServiceRetrySettings(serviceImpl);
|
||||
return serviceImpl;
|
||||
}
|
||||
|
||||
//
|
||||
// /**
|
||||
// * Creates a {@link hirs.persist.PortalInfoManager} ready to use.
|
||||
// * Creates a {@link hirs.attestationca.servicemanager.DBManager}
|
||||
// * for SupplyChainValidationSummary persistence, ready for use.
|
||||
// *
|
||||
// * @return {@link hirs.persist.PortalInfoManager}
|
||||
// * @return {@link hirs.attestationca.servicemanager.DBManager}
|
||||
// */
|
||||
// @Bean
|
||||
// public PortalInfoManager portalInfoManager() {
|
||||
// DBPortalInfoManager manager = new DBPortalInfoManager(entityManager);
|
||||
// setDbServiceRetrySettings(manager);
|
||||
// return manager;
|
||||
// public DbServiceImpl<SupplyChainValidationSummary> supplyChainValidationSummaryManager() {
|
||||
// DbServiceImpl<SupplyChainValidationSummary> serviceImpl
|
||||
// = new DbServiceImpl<SupplyChainValidationSummary>(entityManager);
|
||||
// setDbServiceRetrySettings(serviceImpl);
|
||||
// return serviceImpl;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Creates a {@link hirs.attestationca.servicemanager.DBManager}
|
||||
* for SupplyChainValidationSummary persistence, ready for use.
|
||||
*
|
||||
* @return {@link hirs.attestationca.servicemanager.DBManager}
|
||||
*/
|
||||
@Bean
|
||||
public DbServiceImpl<SupplyChainValidationSummary> supplyChainValidationSummaryManager() {
|
||||
DbServiceImpl<SupplyChainValidationSummary> serviceImpl
|
||||
= new DbServiceImpl<SupplyChainValidationSummary>(
|
||||
entityManager
|
||||
);
|
||||
setDbServiceRetrySettings(serviceImpl);
|
||||
return serviceImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the spring-wired retry template settings to the db manager.
|
||||
* @param dbServiceImpl the service to apply the retry settings to
|
||||
|
@ -13,6 +13,7 @@ import org.springframework.retry.RetryContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -26,12 +27,20 @@ public class AppraiserServiceImpl extends DbServiceImpl<Appraiser>
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
@Autowired
|
||||
private AppraiserRepository appraiserRepository;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @param em entity manager for jpa hibernate events
|
||||
* @param entityManager entity manager for jpa hibernate events
|
||||
*/
|
||||
public AppraiserServiceImpl(final EntityManager em) {
|
||||
public AppraiserServiceImpl(final EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archive(final UUID uuid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,6 +2,7 @@ package hirs.attestationca.service;
|
||||
|
||||
import hirs.FilteredRecordsList;
|
||||
import hirs.attestationca.repository.CertificateRepository;
|
||||
import hirs.data.persist.ArchivableEntity;
|
||||
import hirs.data.persist.certificate.Certificate;
|
||||
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
||||
import hirs.data.persist.certificate.EndorsementCredential;
|
||||
@ -20,6 +21,7 @@ import org.springframework.retry.RetryContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -38,12 +40,15 @@ public class CertificateServiceImpl extends DbServiceImpl<Certificate>
|
||||
private static final Logger LOGGER = LogManager.getLogger(CertificateServiceImpl.class);
|
||||
@Autowired
|
||||
private CertificateRepository certificateRepository;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @param em entity manager for jpa hibernate events
|
||||
* @param entityManager entity manager for jpa hibernate events
|
||||
*/
|
||||
public CertificateServiceImpl(final EntityManager em) {
|
||||
public CertificateServiceImpl(final EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -168,4 +173,25 @@ public class CertificateServiceImpl extends DbServiceImpl<Certificate>
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archive(UUID uuid) {
|
||||
LOGGER.debug("archiving object: {}", uuid);
|
||||
if (uuid == null) {
|
||||
LOGGER.debug("null name argument");
|
||||
return false;
|
||||
}
|
||||
Certificate target = (Certificate)
|
||||
this.certificateRepository.getReferenceById(uuid);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(target instanceof ArchivableEntity)) {
|
||||
throw new DBManagerException("unable to archive non-archivable object");
|
||||
}
|
||||
|
||||
((ArchivableEntity) target).archive();
|
||||
this.updateCertificate(target, uuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,19 @@
|
||||
package hirs.attestationca.service;
|
||||
|
||||
import hirs.data.persist.ArchivableEntity;
|
||||
import hirs.persist.DBManagerException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.jadira.usertype.spi.repository.JpaBaseRepository;
|
||||
import org.springframework.retry.RetryListener;
|
||||
import org.springframework.retry.backoff.FixedBackOffPolicy;
|
||||
import org.springframework.retry.policy.SimpleRetryPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
@ -24,8 +22,7 @@ import java.util.Map;
|
||||
* archive, and delete operations for managing objects in a database.
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class DbServiceImpl<T> {
|
||||
public abstract class DbServiceImpl<T> {
|
||||
private static final Logger LOGGER = LogManager.getLogger(DbServiceImpl.class);
|
||||
|
||||
/**
|
||||
@ -39,7 +36,9 @@ public class DbServiceImpl<T> {
|
||||
|
||||
// structure for retrying methods in the database
|
||||
private RetryTemplate retryTemplate;
|
||||
private EntityManager em;
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Creates a new <code>DbServiceImpl</code> that uses the default database. The
|
||||
@ -53,11 +52,12 @@ public class DbServiceImpl<T> {
|
||||
/**
|
||||
* Creates a new <code>DbServiceImpl</code> that uses the default database. The
|
||||
* default database is used to store all of the objects.
|
||||
* @param entityManager entity manager for jpa hibernate events
|
||||
*
|
||||
*/
|
||||
public DbServiceImpl(final EntityManager em) {
|
||||
public DbServiceImpl(final EntityManager entityManager) {
|
||||
setRetryTemplate(DEFAULT_MAX_RETRY_ATTEMPTS, DEFAULT_RETRY_WAIT_TIME_MS);
|
||||
this.em = em;
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,34 +107,16 @@ public class DbServiceImpl<T> {
|
||||
* @return instance of the manager
|
||||
*/
|
||||
public final EntityManager getEm() {
|
||||
return em;
|
||||
return entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Archives the named object and updates it in the database.
|
||||
*
|
||||
* @param name name of the object to archive
|
||||
* @param uuid unique id of the object to archive
|
||||
* @return true if the object was successfully found and archived, false if the object was not
|
||||
* found
|
||||
* @throws hirs.persist.DBManagerException if the object is not an instance of <code>ArchivableEntity</code>
|
||||
*/
|
||||
public final boolean archive(final String name) throws DBManagerException {
|
||||
LOGGER.debug("archiving object: {}", name);
|
||||
if (name == null) {
|
||||
LOGGER.debug("null name argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
T target = get(name);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(target instanceof ArchivableEntity)) {
|
||||
throw new DBManagerException("unable to archive non-archivable object");
|
||||
}
|
||||
|
||||
((ArchivableEntity) target).archive();
|
||||
update(target);
|
||||
return true;
|
||||
}
|
||||
public abstract boolean archive(final UUID uuid);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import org.springframework.retry.RetryContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -32,12 +33,15 @@ public class DeviceServiceImpl extends DbServiceImpl<Device>
|
||||
private static final Logger LOGGER = LogManager.getLogger(DeviceServiceImpl.class);
|
||||
@Autowired
|
||||
private DeviceRepository deviceRepository;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @param em entity manager for jpa hibernate events
|
||||
* @param entityManager entity manager for jpa hibernate events
|
||||
*/
|
||||
public DeviceServiceImpl(final EntityManager em) {
|
||||
public DeviceServiceImpl(final EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -147,4 +151,9 @@ public class DeviceServiceImpl extends DbServiceImpl<Device>
|
||||
throws DBManagerException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archive(UUID uuid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package hirs.attestationca.service;
|
||||
import hirs.FilteredRecordsList;
|
||||
import hirs.appraiser.Appraiser;
|
||||
import hirs.attestationca.repository.PolicyRepository;
|
||||
import hirs.data.persist.ArchivableEntity;
|
||||
import hirs.data.persist.policy.Policy;
|
||||
import hirs.persist.CriteriaModifier;
|
||||
import hirs.persist.DBManagerException;
|
||||
@ -20,6 +21,7 @@ import org.springframework.retry.RetryContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
@ -40,12 +42,16 @@ public class PolicyServiceImpl extends DbServiceImpl<Policy>
|
||||
private static final Logger LOGGER = LogManager.getLogger(PolicyServiceImpl.class);
|
||||
@Autowired
|
||||
private PolicyRepository policyRepository;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
* @param entityManager entity manager for jpa hibernate events
|
||||
*/
|
||||
public PolicyServiceImpl(final EntityManager em) {
|
||||
super(em);
|
||||
public PolicyServiceImpl(final EntityManager entityManager) {
|
||||
super(entityManager);
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -185,4 +191,25 @@ public class PolicyServiceImpl extends DbServiceImpl<Policy>
|
||||
throws DBManagerException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archive(UUID uuid) {
|
||||
LOGGER.debug("archiving object: {}", uuid);
|
||||
if (uuid == null) {
|
||||
LOGGER.debug("null name argument");
|
||||
return false;
|
||||
}
|
||||
Policy target = (Policy)
|
||||
this.policyRepository.getReferenceById(uuid);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(target instanceof ArchivableEntity)) {
|
||||
throw new DBManagerException("unable to archive non-archivable object");
|
||||
}
|
||||
|
||||
((ArchivableEntity) target).archive();
|
||||
this.updatePolicy(target, uuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package hirs.attestationca.service;
|
||||
|
||||
import hirs.FilteredRecordsList;
|
||||
import hirs.attestationca.repository.ReferenceDigestValueRepository;
|
||||
import hirs.data.persist.ArchivableEntity;
|
||||
import hirs.data.persist.ReferenceDigestValue;
|
||||
import hirs.persist.CriteriaModifier;
|
||||
import hirs.persist.DBManagerException;
|
||||
@ -15,6 +16,8 @@ import org.springframework.retry.RetryContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -32,11 +35,15 @@ public class ReferenceDigestValueServiceImpl extends DbServiceImpl<ReferenceDige
|
||||
.getLogger(ReferenceDigestValueServiceImpl.class);
|
||||
@Autowired
|
||||
private ReferenceDigestValueRepository referenceDigestValueRepository;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
* @param entityManager entity manager for jpa hibernate events
|
||||
*/
|
||||
public ReferenceDigestValueServiceImpl(final EntityManager em) {
|
||||
public ReferenceDigestValueServiceImpl(final EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -145,7 +152,27 @@ public class ReferenceDigestValueServiceImpl extends DbServiceImpl<ReferenceDige
|
||||
final boolean ascending, final int firstResult, final int maxResults,
|
||||
final String search, final Map<String, Boolean> searchableColumns)
|
||||
throws DBManagerException {
|
||||
return null;
|
||||
LOGGER.debug("Getting ordered object list");
|
||||
Class<ReferenceDigestValue> searchClass = clazz;
|
||||
if (clazz == null) {
|
||||
LOGGER.debug("clazz is null");
|
||||
searchClass = ReferenceDigestValue.class;
|
||||
}
|
||||
|
||||
if (searchableColumns != null) {
|
||||
LOGGER.info(searchClass.getName() + " querying for "
|
||||
+ Arrays.toString(searchableColumns.entrySet().toArray())
|
||||
+ " with search strings \"" + search + "\"");
|
||||
}
|
||||
|
||||
//Object that will store query values
|
||||
FilteredRecordsList<ReferenceDigestValue> rdvOrderedList = new FilteredRecordsList<>();
|
||||
|
||||
// Search
|
||||
// Query keywordQuery = queryBuilder.
|
||||
|
||||
// sort
|
||||
return rdvOrderedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -157,4 +184,25 @@ public class ReferenceDigestValueServiceImpl extends DbServiceImpl<ReferenceDige
|
||||
throws DBManagerException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archive(UUID uuid) {
|
||||
LOGGER.debug("archiving object: {}", uuid);
|
||||
if (uuid == null) {
|
||||
LOGGER.debug("null name argument");
|
||||
return false;
|
||||
}
|
||||
ReferenceDigestValue target = (ReferenceDigestValue)
|
||||
this.referenceDigestValueRepository.getReferenceById(uuid);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(target instanceof ArchivableEntity)) {
|
||||
throw new DBManagerException("unable to archive non-archivable object");
|
||||
}
|
||||
|
||||
((ArchivableEntity) target).archive();
|
||||
this.updateDigestValue(target, uuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ package hirs.attestationca.service;
|
||||
|
||||
import hirs.FilteredRecordsList;
|
||||
import hirs.attestationca.repository.ReferenceManifestRepository;
|
||||
import hirs.data.persist.ArchivableEntity;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.persist.CriteriaModifier;
|
||||
import hirs.persist.DBManagerException;
|
||||
import hirs.persist.service.DefaultService;
|
||||
import hirs.persist.ReferenceManifestSelector;
|
||||
import hirs.persist.service.ReferenceManifestService;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -15,8 +16,11 @@ import org.springframework.retry.RetryContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -26,11 +30,13 @@ import java.util.UUID;
|
||||
*/
|
||||
@Service
|
||||
public class ReferenceManifestServiceImpl extends DbServiceImpl<ReferenceManifest>
|
||||
implements DefaultService<ReferenceManifest>, ReferenceManifestService {
|
||||
implements ReferenceManifestService {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(ReferenceManifestServiceImpl.class);
|
||||
@Autowired
|
||||
private ReferenceManifestRepository referenceManifestRepository;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
@ -79,6 +85,12 @@ public class ReferenceManifestServiceImpl extends DbServiceImpl<ReferenceManifes
|
||||
deleteObjectById(rim.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ReferenceManifest> Set<T> getReferenceManifest(
|
||||
final ReferenceManifestSelector referenceManifestSelector) {
|
||||
return new HashSet<>(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReferenceManifest> getList() {
|
||||
LOGGER.debug("Getting all reference manifest...");
|
||||
@ -137,4 +149,25 @@ public class ReferenceManifestServiceImpl extends DbServiceImpl<ReferenceManifes
|
||||
throws DBManagerException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archive(final UUID uuid) throws DBManagerException {
|
||||
LOGGER.debug("archiving object: {}", uuid);
|
||||
if (uuid == null) {
|
||||
LOGGER.debug("null name argument");
|
||||
return false;
|
||||
}
|
||||
ReferenceManifest target = (ReferenceManifest)
|
||||
this.referenceManifestRepository.getReferenceById(uuid);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(target instanceof ArchivableEntity)) {
|
||||
throw new DBManagerException("unable to archive non-archivable object");
|
||||
}
|
||||
|
||||
((ArchivableEntity) target).archive();
|
||||
this.updateReferenceManifest(target, uuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -219,8 +219,7 @@ public abstract class ReferenceManifestSelector<T extends ReferenceManifest> {
|
||||
|
||||
// construct and execute query
|
||||
private Set<T> execute() {
|
||||
Set<T> results = this.referenceManifestService.ge;
|
||||
return results;
|
||||
return this.referenceManifestService.getReferenceManifest(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,9 @@ package hirs.persist.service;
|
||||
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.persist.OrderedQuery;
|
||||
import hirs.persist.ReferenceManifestSelector;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -10,7 +12,8 @@ import java.util.UUID;
|
||||
* <code>ReferenceManifestService</code> is used to store and manage reference manifests. It has
|
||||
* support for the basic create, read, update, and delete methods.
|
||||
*/
|
||||
public interface ReferenceManifestService extends OrderedQuery<ReferenceManifest> {
|
||||
public interface ReferenceManifestService extends OrderedQuery<ReferenceManifest>,
|
||||
DefaultService<ReferenceManifest> {
|
||||
|
||||
/**
|
||||
* Saves the <code>ReferenceManifest</code> in the database. This creates a new
|
||||
@ -39,4 +42,16 @@ public interface ReferenceManifestService extends OrderedQuery<ReferenceManifest
|
||||
* @return reference to deleted rim
|
||||
*/
|
||||
void deleteRIM(ReferenceManifest rim);
|
||||
|
||||
/**
|
||||
* Retrieve Reference Manifest according to the given
|
||||
* {@link hirs.persist.ReferenceManifestSelector}.
|
||||
*
|
||||
* @param <T> the type of certificate that will be retrieved
|
||||
* @param referenceManifestSelector a {@link hirs.persist.ReferenceManifestSelector}
|
||||
* to use for querying
|
||||
* @return a Set of matching Certificates, which may be empty
|
||||
*/
|
||||
<T extends ReferenceManifest> Set<T> getReferenceManifest(
|
||||
ReferenceManifestSelector referenceManifestSelector);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user