mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 12:30:15 +02:00
Added group management
This commit is contained in:
parent
ac7cd5670f
commit
190947f18d
@ -0,0 +1,3 @@
|
|||||||
|
from util import bootstrap_permissions
|
||||||
|
|
||||||
|
bootstrap_permissions()
|
@ -58,6 +58,7 @@ INSTALLED_APPS = (
|
|||||||
'registration',
|
'registration',
|
||||||
'services',
|
'services',
|
||||||
'eveonline',
|
'eveonline',
|
||||||
|
'groupmanagement'
|
||||||
)
|
)
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
|
@ -34,6 +34,19 @@ urlpatterns = patterns('',
|
|||||||
url(r'^characters/', 'eveonline.views.characters_view', name='auth_characters'),
|
url(r'^characters/', 'eveonline.views.characters_view', name='auth_characters'),
|
||||||
url(r'^main_character_change/(\w+)/$', 'eveonline.views.main_character_change', name='auth_main_character_change'),
|
url(r'^main_character_change/(\w+)/$', 'eveonline.views.main_character_change', name='auth_main_character_change'),
|
||||||
|
|
||||||
|
# Group management
|
||||||
|
url(r'^groups/', 'groupmanagement.views.groups_view', name='auth_groups'),
|
||||||
|
url(r'^group/management/', 'groupmanagement.views.group_management', name='auth_group_management'),
|
||||||
|
url(r'^group/request_add/(\w+)', 'groupmanagement.views.group_request_add', name='auth_group_request_add'),
|
||||||
|
url(r'^group/request/accept/(\w+)', 'groupmanagement.views.group_accept_request', name='auth_group_accept_request'),
|
||||||
|
url(r'^group/request/reject/(\w+)', 'groupmanagement.views.group_reject_request', name='auth_group_reject_request'),
|
||||||
|
|
||||||
|
url(r'^group/request_leave/(\w+)', 'groupmanagement.views.group_request_leave', name='auth_group_request_leave'),
|
||||||
|
url(r'group/leave_request/accept/(\w+)', 'groupmanagement.views.group_leave_accept_request',
|
||||||
|
name='auth_group_leave_accept_request'),
|
||||||
|
url(r'^group/leave_request/reject/(\w+)', 'groupmanagement.views.group_leave_reject_request',
|
||||||
|
name='auth_group_leave_reject_request'),
|
||||||
|
|
||||||
# Service Urls
|
# Service Urls
|
||||||
url(r'^services/', 'services.views.services_view', name='auth_services'),
|
url(r'^services/', 'services.views.services_view', name='auth_services'),
|
||||||
|
|
||||||
|
@ -15,4 +15,4 @@ class AuthServicesInfo(models.Model):
|
|||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.user.username
|
return self.user.username + ' - AuthInfo'
|
@ -23,4 +23,4 @@ class EveApiKeyPair(models.Model):
|
|||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.user.username
|
return self.user.username + " - ApiKeyPair"
|
@ -17,6 +17,7 @@ from util.common_task import remove_user_from_group
|
|||||||
from util.common_task import deactivate_services
|
from util.common_task import deactivate_services
|
||||||
from util.common_task import generate_corp_group_name
|
from util.common_task import generate_corp_group_name
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def add_api_key(request):
|
def add_api_key(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
0
groupmanagement/__init__.py
Normal file
0
groupmanagement/__init__.py
Normal file
6
groupmanagement/admin.py
Normal file
6
groupmanagement/admin.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from models import GroupDescription
|
||||||
|
from models import GroupRequest
|
||||||
|
|
||||||
|
admin.site.register(GroupDescription)
|
||||||
|
admin.site.register(GroupRequest)
|
23
groupmanagement/models.py
Normal file
23
groupmanagement/models.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
from eveonline.models import EveCharacter
|
||||||
|
|
||||||
|
|
||||||
|
class GroupDescription(models.Model):
|
||||||
|
description = models.CharField(max_length=512)
|
||||||
|
group = models.ForeignKey(Group, unique=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.group.name + " - Description"
|
||||||
|
|
||||||
|
|
||||||
|
class GroupRequest(models.Model):
|
||||||
|
status = models.CharField(max_length=254)
|
||||||
|
leave_request = models.BooleanField(default=0)
|
||||||
|
user = models.ForeignKey(User)
|
||||||
|
group = models.ForeignKey(Group)
|
||||||
|
main_char = models.ForeignKey(EveCharacter)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user.username + ":" + self.group.name
|
3
groupmanagement/tests.py
Normal file
3
groupmanagement/tests.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
145
groupmanagement/views.py
Normal file
145
groupmanagement/views.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
from django.template import RequestContext
|
||||||
|
from django.shortcuts import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib.auth.decorators import permission_required
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from models import GroupDescription
|
||||||
|
from models import GroupRequest
|
||||||
|
|
||||||
|
from authentication.managers import AuthServicesInfoManager
|
||||||
|
from eveonline.managers import EveManager
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('auth.group_management')
|
||||||
|
def group_management(request):
|
||||||
|
acceptrequests = []
|
||||||
|
leaverequests = []
|
||||||
|
|
||||||
|
for grouprequest in GroupRequest.objects.all():
|
||||||
|
if grouprequest.leave_request:
|
||||||
|
leaverequests.append(grouprequest)
|
||||||
|
else:
|
||||||
|
acceptrequests.append(grouprequest)
|
||||||
|
|
||||||
|
render_items = {'acceptrequests': acceptrequests, 'leaverequests': leaverequests}
|
||||||
|
|
||||||
|
return render_to_response('registered/groupmanagement.html',
|
||||||
|
render_items, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('auth.group_management')
|
||||||
|
def group_accept_request(request, group_request_id):
|
||||||
|
try:
|
||||||
|
group_request = GroupRequest.objects.get(id=group_request_id)
|
||||||
|
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
||||||
|
request.user.groups.add(group)
|
||||||
|
request.user.save()
|
||||||
|
group_request.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return HttpResponseRedirect("/group/management/")
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('auth.group_management')
|
||||||
|
def group_reject_request(request, group_request_id):
|
||||||
|
try:
|
||||||
|
group_request = GroupRequest.objects.get(id=group_request_id)
|
||||||
|
|
||||||
|
if group_request:
|
||||||
|
group_request.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return HttpResponseRedirect("/group/management/")
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('auth.group_management')
|
||||||
|
def group_leave_accept_request(request, group_request_id):
|
||||||
|
try:
|
||||||
|
group_request = GroupRequest.objects.get(id=group_request_id)
|
||||||
|
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
||||||
|
request.user.groups.remove(group)
|
||||||
|
request.user.save()
|
||||||
|
group_request.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return HttpResponseRedirect("/group/management/")
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('auth.group_management')
|
||||||
|
def group_leave_reject_request(request, group_request_id):
|
||||||
|
try:
|
||||||
|
group_request = GroupRequest.objects.get(id=group_request_id)
|
||||||
|
|
||||||
|
if group_request:
|
||||||
|
group_request.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return HttpResponseRedirect("/group/management/")
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def groups_view(request):
|
||||||
|
|
||||||
|
paired_list = []
|
||||||
|
|
||||||
|
for group in Group.objects.all():
|
||||||
|
# Check if group is a corp
|
||||||
|
if "Corp" in group.name:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Get the descriptionn
|
||||||
|
groupDesc = GroupDescription.objects.filter(group=group)
|
||||||
|
groupRequest = GroupRequest.objects.filter(user=request.user).filter(group=group)
|
||||||
|
|
||||||
|
if groupDesc:
|
||||||
|
if groupRequest:
|
||||||
|
paired_list.append((group, groupDesc[0], groupRequest[0]))
|
||||||
|
else:
|
||||||
|
paired_list.append((group, groupDesc[0], ""))
|
||||||
|
else:
|
||||||
|
if groupRequest:
|
||||||
|
paired_list.append((group, "", groupRequest[0]))
|
||||||
|
else:
|
||||||
|
paired_list.append((group, "", ""))
|
||||||
|
|
||||||
|
render_items = {'pairs': paired_list}
|
||||||
|
return render_to_response('registered/groups.html',
|
||||||
|
render_items, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def group_request_add(request, group_id):
|
||||||
|
auth_info = AuthServicesInfoManager.get_auth_service_info(request.user)
|
||||||
|
grouprequest = GroupRequest()
|
||||||
|
grouprequest.status = 'pending'
|
||||||
|
grouprequest.group = Group.objects.get(id=group_id)
|
||||||
|
grouprequest.user = request.user
|
||||||
|
grouprequest.main_char = EveManager.get_character_by_id(auth_info.main_char_id)
|
||||||
|
grouprequest.leave_request = False
|
||||||
|
grouprequest.save()
|
||||||
|
|
||||||
|
return HttpResponseRedirect("/groups")
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def group_request_leave(request, group_id):
|
||||||
|
auth_info = AuthServicesInfoManager.get_auth_service_info(request.user)
|
||||||
|
grouprequest = GroupRequest()
|
||||||
|
grouprequest.status = 'pending'
|
||||||
|
grouprequest.group = Group.objects.get(id=group_id)
|
||||||
|
grouprequest.user = request.user
|
||||||
|
grouprequest.main_char = EveManager.get_character_by_id(auth_info.main_char_id)
|
||||||
|
grouprequest.leave_request = True
|
||||||
|
grouprequest.save()
|
||||||
|
|
||||||
|
return HttpResponseRedirect("/groups")
|
@ -65,6 +65,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<a {% ifequal request.path "/api_key_management/" %} class="active" {% endifequal %} href="{% url 'auth_api_key_management' %}"><i class="fa fa-key fa-fw"></i> Api Keys</a>
|
<a {% ifequal request.path "/api_key_management/" %} class="active" {% endifequal %} href="{% url 'auth_api_key_management' %}"><i class="fa fa-key fa-fw"></i> Api Keys</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a {% ifequal request.path "/groups/" %} class="active" {% endifequal %} href="{% url 'auth_groups' %}"><i class="fa fa-cogs fa-sitemap"></i> Groups</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a {% ifequal request.path "/services/" %} class="active" {% endifequal %} href="{% url 'auth_services' %}"><i class="fa fa-cogs fa-fw"></i> Services</a>
|
<a {% ifequal request.path "/services/" %} class="active" {% endifequal %} href="{% url 'auth_services' %}"><i class="fa fa-cogs fa-fw"></i> Services</a>
|
||||||
</li>
|
</li>
|
||||||
@ -78,6 +81,11 @@
|
|||||||
<li>
|
<li>
|
||||||
<a {% ifequal request.path "/user/password/" %} class="active" {% endifequal %} href="{% url 'password_change' %}"><i class="fa fa-lock fa-fw"></i>Change Password</a>
|
<a {% ifequal request.path "/user/password/" %} class="active" {% endifequal %} href="{% url 'password_change' %}"><i class="fa fa-lock fa-fw"></i>Change Password</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if perms.auth.group_management %}
|
||||||
|
<li>
|
||||||
|
<a {% ifequal request.path "/user/group_management/" %} class="active" {% endifequal %} href="{% url 'auth_group_management' %}"><i class="fa fa-lock fa-sitemap"></i> Group Management</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{% block title %}Alliance Auth{% endblock %}
|
{% block title %}Alliance Auth{% endblock %}
|
||||||
|
|
||||||
{% block page_title %}Something something here{% endblock page_title %}
|
{% block page_title %}Add Api Key{% endblock page_title %}
|
||||||
{% block extra_css %}{% endblock extra_css %}
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{% block title %}Alliance Auth{% endblock %}
|
{% block title %}Alliance Auth{% endblock %}
|
||||||
|
|
||||||
{% block page_title %}Something something here{% endblock page_title %}
|
{% block page_title %}API Key Management{% endblock page_title %}
|
||||||
{% block extra_css %}{% endblock extra_css %}
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{% block title %}Alliance Auth{% endblock %}
|
{% block title %}Alliance Auth{% endblock %}
|
||||||
|
|
||||||
{% block page_title %}Something something here{% endblock page_title %}
|
{% block page_title %}Characters{% endblock page_title %}
|
||||||
{% block extra_css %}{% endblock extra_css %}
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
75
templates/registered/groupmanagement.html
Normal file
75
templates/registered/groupmanagement.html
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{% extends "public/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block title %}Alliance Auth{% endblock %}
|
||||||
|
|
||||||
|
{% block page_title %}Groups Management{% endblock page_title %}
|
||||||
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h3 class="page-header text-center">Group Management</h3>
|
||||||
|
<h4 class="page-header text-center">Group Add Request</h4>
|
||||||
|
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">RequestID</th>
|
||||||
|
<th class="text-center">CharacterName</th>
|
||||||
|
<th class="text-center">GroupName</th>
|
||||||
|
<th class="text-center">Action</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for acceptrequest in acceptrequests %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">{{ acceptrequest.id }}</td>
|
||||||
|
<td class="text-center">{{ acceptrequest.main_char.character_name }}</td>
|
||||||
|
<td class="text-center">{{ acceptrequest.group.name }}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a href="/group/request/accept/{{ acceptrequest.id }}">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Accept
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/group/request/reject/{{ acceptrequest.id }}">
|
||||||
|
<button type="button" class="btn btn-danger">
|
||||||
|
Reject
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<h4 class="page-header text-center">Group Leave Request</h4>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">RequestID</th>
|
||||||
|
<th class="text-center">CharacterName</th>
|
||||||
|
<th class="text-center">GroupName</th>
|
||||||
|
<th class="text-center">Action</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for leaverequest in leaverequests %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">{{ leaverequest.id }}</td>
|
||||||
|
<td class="text-center">{{ leaverequest.main_char.character_name }}</td>
|
||||||
|
<td class="text-center">{{ leaverequest.group.name }}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a href="/group/leave_request/accept/{{ leaverequest.id }}">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Accept
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/group/leave_request/reject/{{ leaverequest.id }}">
|
||||||
|
<button type="button" class="btn btn-danger">
|
||||||
|
Reject
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock content %}
|
59
templates/registered/groups.html
Normal file
59
templates/registered/groups.html
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{% extends "public/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block title %}Alliance Auth{% endblock %}
|
||||||
|
|
||||||
|
{% block page_title %}Available{% endblock page_title %}
|
||||||
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1 class="page-header text-center">Available Groups</h1>
|
||||||
|
{% if perms.auth.alliance_member %}
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">GroupID</th>
|
||||||
|
<th class="text-center">GroupName</th>
|
||||||
|
<th class="text-center">GroupDesc</th>
|
||||||
|
<th class="text-center">Action</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for pair in pairs %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">{{ pair.0.id }}</td>
|
||||||
|
<td class="text-center">{{ pair.0.name }}</td>
|
||||||
|
<td class="text-center">{{ pair.1.description }}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
{% if pair.0 in user.groups.all %}
|
||||||
|
{% if pair.2 == ""%}
|
||||||
|
<a href="/group/request_leave/{{pair.0.id}}">
|
||||||
|
<button type="button" class="btn btn-danger">
|
||||||
|
Leave
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<button type="button" class="btn btn-primary" disabled>
|
||||||
|
{{ pair.2.status }}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
{% elif pair.2 == "" %}
|
||||||
|
<a href="/group/request_add/{{pair.0.id}}">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Request
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<button type="button" class="btn btn-primary" disabled>
|
||||||
|
{{ pair.2.status }}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-danger" role="alert">You are not in the alliance</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock content %}
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{% block title %}Alliance Auth{% endblock %}
|
{% block title %}Alliance Auth{% endblock %}
|
||||||
|
|
||||||
{% block page_title %}Something something here{% endblock page_title %}
|
{% block page_title %}Services Management{% endblock page_title %}
|
||||||
{% block extra_css %}{% endblock extra_css %}
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@ -56,6 +56,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
</td>
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">Mumble</td>
|
<td class="text-center">Mumble</td>
|
||||||
<td class="text-center">{{ authinfo.mumble_username }}</td>
|
<td class="text-center">{{ authinfo.mumble_username }}</td>
|
||||||
|
@ -3,6 +3,12 @@ from django.contrib.auth.models import User
|
|||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
|
|
||||||
|
def bootstrap_permissions():
|
||||||
|
ct = ContentType.objects.get_for_model(User)
|
||||||
|
stored_permission, created = Permission.objects.get_or_create(codename="group_management",
|
||||||
|
content_type=ct, name="group_management")
|
||||||
|
|
||||||
|
|
||||||
def add_member_permission(user, permission):
|
def add_member_permission(user, permission):
|
||||||
ct = ContentType.objects.get_for_model(User)
|
ct = ContentType.objects.get_for_model(User)
|
||||||
stored_permission, created = Permission.objects.get_or_create(codename=permission,
|
stored_permission, created = Permission.objects.get_or_create(codename=permission,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user