mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Register all CMIS Action Evaluators as per spec.
- add ParentActionEvaluator - add logging of registration git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13824 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -38,6 +38,7 @@ import org.alfresco.cmis.CMISDictionaryModel;
|
|||||||
import org.alfresco.cmis.CMISPropertyId;
|
import org.alfresco.cmis.CMISPropertyId;
|
||||||
import org.alfresco.cmis.CMISScope;
|
import org.alfresco.cmis.CMISScope;
|
||||||
import org.alfresco.cmis.CMISTypeId;
|
import org.alfresco.cmis.CMISTypeId;
|
||||||
|
import org.alfresco.cmis.dictionary.CMISAbstractDictionaryService;
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
@@ -48,6 +49,8 @@ import org.alfresco.service.cmr.security.PermissionService;
|
|||||||
import org.alfresco.service.namespace.NamespaceException;
|
import org.alfresco.service.namespace.NamespaceException;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
|
||||||
@@ -58,6 +61,9 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
*/
|
*/
|
||||||
public class CMISMapping implements InitializingBean
|
public class CMISMapping implements InitializingBean
|
||||||
{
|
{
|
||||||
|
// Logger
|
||||||
|
protected static final Log logger = LogFactory.getLog(CMISMapping.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Alfresco CMIS model URI.
|
* The Alfresco CMIS model URI.
|
||||||
*/
|
*/
|
||||||
@@ -197,24 +203,60 @@ public class CMISMapping implements InitializingBean
|
|||||||
// Action Evaluator Mappings
|
// Action Evaluator Mappings
|
||||||
//
|
//
|
||||||
|
|
||||||
registerActionEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, PermissionService.DELETE_NODE));
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, PermissionService.DELETE_NODE));
|
||||||
registerActionEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, PermissionService.WRITE_PROPERTIES));
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, PermissionService.WRITE_PROPERTIES));
|
||||||
registerActionEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, PermissionService.READ_PROPERTIES));
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, PermissionService.READ_PROPERTIES));
|
||||||
registerActionEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RELATIONSHIPS, true));
|
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RELATIONSHIPS, true));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PARENTS, true));
|
||||||
|
// Is CAN_MOVE correct mapping?
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_MOVE, PermissionService.DELETE_NODE));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE_VERSION, PermissionService.DELETE_NODE));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE_CONTENT, PermissionService.WRITE_PROPERTIES, PermissionService.WRITE_CONTENT));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CHECKOUT, PermissionService.CHECK_OUT));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CANCEL_CHECKOUT, PermissionService.CANCEL_CHECK_OUT));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CHECKIN, PermissionService.CHECK_IN));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_SET_CONTENT, PermissionService.WRITE_CONTENT));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_ALL_VERSIONS, true));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new ParentActionEvaluator(new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_ADD_TO_FOLDER, PermissionService.LINK_CHILDREN)));
|
||||||
|
// Is CAN_REMOVE_FROM_FOLDER correct mapping?
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new ParentActionEvaluator(new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_FROM_FOLDER, true)));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_VIEW_CONTENT, PermissionService.READ_CONTENT));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_ADD_POLICY, false));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_APPLIED_POLICIES, false));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_POLICY, false));
|
||||||
|
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_RELATIONSHIP, PermissionService.CREATE_ASSOCIATIONS));
|
||||||
|
|
||||||
registerActionEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, PermissionService.DELETE_NODE));
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, PermissionService.DELETE_NODE));
|
||||||
registerActionEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, PermissionService.WRITE_PROPERTIES));
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, PermissionService.WRITE_PROPERTIES));
|
||||||
registerActionEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, PermissionService.READ_PROPERTIES));
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, PermissionService.READ_PROPERTIES));
|
||||||
registerActionEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RELATIONSHIPS, true));
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RELATIONSHIPS, true));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PARENTS, true));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_FOLDER_PARENT, true));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_DESCENDANTS, PermissionService.READ_CHILDREN));
|
||||||
|
// Is CAN_MOVE correct mapping?
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_MOVE, PermissionService.DELETE_NODE));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_ADD_POLICY, false));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_APPLIED_POLICIES, false));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_POLICY, false));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_CHILDREN, PermissionService.READ_CHILDREN));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_DOCUMENT, PermissionService.CREATE_CHILDREN));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_FOLDER, PermissionService.CREATE_CHILDREN));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_RELATIONSHIP, PermissionService.CREATE_ASSOCIATIONS));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_POLICY, false));
|
||||||
|
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE_TREE, PermissionService.DELETE_NODE));
|
||||||
|
|
||||||
registerActionEvaluator(CMISScope.RELATIONSHIP, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, true));
|
registerEvaluator(CMISScope.RELATIONSHIP, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, true));
|
||||||
registerActionEvaluator(CMISScope.RELATIONSHIP, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, false));
|
registerEvaluator(CMISScope.RELATIONSHIP, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, false));
|
||||||
registerActionEvaluator(CMISScope.RELATIONSHIP, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, false));
|
registerEvaluator(CMISScope.RELATIONSHIP, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, false));
|
||||||
|
|
||||||
registerActionEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, false));
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_DELETE, false));
|
||||||
registerActionEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, false));
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_UPDATE_PROPERTIES, false));
|
||||||
registerActionEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, false));
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PROPERTIES, false));
|
||||||
registerActionEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RELATIONSHIPS, false));
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RELATIONSHIPS, false));
|
||||||
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_PARENTS, false));
|
||||||
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_MOVE, false));
|
||||||
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_ADD_TO_FOLDER, false));
|
||||||
|
registerEvaluator(CMISScope.POLICY, new FixedValueActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_FROM_FOLDER, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -741,7 +783,7 @@ public class CMISMapping implements InitializingBean
|
|||||||
* @param scope
|
* @param scope
|
||||||
* @param evaluator
|
* @param evaluator
|
||||||
*/
|
*/
|
||||||
private void registerActionEvaluator(CMISScope scope, CMISActionEvaluator evaluator)
|
private void registerEvaluator(CMISScope scope, CMISActionEvaluator evaluator)
|
||||||
{
|
{
|
||||||
Map<CMISAllowedActionEnum, CMISActionEvaluator> evaluators = actionEvaluators.get(scope);
|
Map<CMISAllowedActionEnum, CMISActionEvaluator> evaluators = actionEvaluators.get(scope);
|
||||||
if (evaluators == null)
|
if (evaluators == null)
|
||||||
@@ -754,6 +796,9 @@ public class CMISMapping implements InitializingBean
|
|||||||
throw new AlfrescoRuntimeException("Already registered Action Evaluator " + evaluator.getAction() + " for scope " + scope);
|
throw new AlfrescoRuntimeException("Already registered Action Evaluator " + evaluator.getAction() + " for scope " + scope);
|
||||||
}
|
}
|
||||||
evaluators.put(evaluator.getAction(), evaluator);
|
evaluators.put(evaluator.getAction(), evaluator);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Registered Action Evaluator: scope=" + scope + ", evaluator=" + evaluator);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ import org.alfresco.service.ServiceRegistry;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alfresco Permission based Action Evaluator
|
* Action Evaluator whose evaluation is fixed
|
||||||
*
|
*
|
||||||
* @author davidc
|
* @author davidc
|
||||||
*
|
*
|
||||||
@@ -58,4 +58,13 @@ public class FixedValueActionEvaluator extends AbstractActionEvaluator
|
|||||||
{
|
{
|
||||||
return allowed;
|
return allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("FixedValueActionEvaluator[action=").append(getAction());
|
||||||
|
builder.append(", allowed=").append(allowed).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.cmis.mapping;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action Evaluator whose evaluation takes place on parent
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
public class ParentActionEvaluator extends AbstractActionEvaluator
|
||||||
|
{
|
||||||
|
private AbstractActionEvaluator evaluator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct
|
||||||
|
*
|
||||||
|
* @param serviceRegistry
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
|
protected ParentActionEvaluator(AbstractActionEvaluator evaluator)
|
||||||
|
{
|
||||||
|
super(evaluator.getServiceRegistry(), evaluator.getAction());
|
||||||
|
this.evaluator = evaluator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.cmis.CMISActionEvaluator#isAllowed(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
|
*/
|
||||||
|
public boolean isAllowed(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
if (nodeRef.equals(getServiceRegistry().getCMISService().getDefaultRootNodeRef()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChildAssociationRef car = getServiceRegistry().getNodeService().getPrimaryParent(nodeRef);
|
||||||
|
if ((car != null) && (car.getParentRef() != null))
|
||||||
|
{
|
||||||
|
return evaluator.isAllowed(car.getParentRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("ParentActionEvaluator[evaluator=").append(evaluator).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -34,7 +34,6 @@ import org.alfresco.service.cmr.security.PermissionService;
|
|||||||
* Alfresco Permission based Action Evaluator
|
* Alfresco Permission based Action Evaluator
|
||||||
*
|
*
|
||||||
* @author davidc
|
* @author davidc
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class PermissionActionEvaluator extends AbstractActionEvaluator
|
public class PermissionActionEvaluator extends AbstractActionEvaluator
|
||||||
{
|
{
|
||||||
@@ -69,4 +68,19 @@ public class PermissionActionEvaluator extends AbstractActionEvaluator
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("PermissionActionEvaluator[action=").append(getAction());
|
||||||
|
builder.append(", permissions=");
|
||||||
|
for (String permission : permissions)
|
||||||
|
{
|
||||||
|
builder.append(permission).append(",");
|
||||||
|
}
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user