- Changed HTML to support the new fancy ban system
- Added "banned" and "active_ban" bits in models.py
- IP bans are supported now.
This commit is contained in:
some weird guy
2023-08-24 12:20:32 -07:00
parent ca09f3295b
commit e49d856f71
10 changed files with 60 additions and 194 deletions
+4 -2
View File
@@ -18,8 +18,10 @@ Stuff that is in progress
- New Ban system. - New Ban system.
Bans are here also with its own interface. Bans are here also with its own interface.
Instead of entering a datetime field manually, Admins are provided with choises for different ban lengths when using the frontend. Theres no way to unban a user when using the ban page.
IP bans and range bans are not added yet. Instead of entering a datetime field manually, Admins are provided with choises for different ban lengths when using the ban page.
IP bans are here but range bans are not added yet.
IPs are banned automatically when using the ban page.
A proper ban page is not added yet and simply shows a 403 error. A proper ban page is not added yet and simply shows a 403 error.
If a ban page is added, it should show the reason, and when the ban will expire. If a ban page is added, it should show the reason, and when the ban will expire.
There's no javascript for the form page yet. There's no javascript for the form page yet.
+4 -143
View File
@@ -1,146 +1,7 @@
# About # Cedar-Django
Cedar-Django is a fork of Closedverse with custom features added to it.
### Theme changing https://youtu.be/uUiJCG06bdA
Just like in Indigo, you can change the color of your theme. While this is only visible to each user specifically, a global theme can be set in Settings.py.
### Overhauled admin panel Alright, I know I will eventually have to write the documentation, but fuuuuuuck I really don't want to do it.
The admin panel has been changed completely. You can now do a lot more things in a much easier way. The intention behind this redesign is to reduce the need to use the normal Django admin panel.
### Community creation It's a standard Django app, You'll have to somehow set it up either with python3 manage.py runserver, or through nginx or whatever.
You can have your users make communities. Each user by default can make one community. User communities can be changed by the owner of said community.
### Password resetting within the settings page
**This should've been a thing since day one.** Instead of being forced to reset your password through your email, you can now change it via settings.
### Invite only features
**You can set `invite_only` to `True` if you want your site to be invite only** If you choose to make your website invite only, users can create invite codes and send them to others as a means of inviting new people to the website. Upon signing up, users are required to input a valid invite code in order to create an account. This can be useful for closed off communities or as a ditch effort to stop raids or whatever.
Moderators and staff will be able to revoke a user's ability to add new users if need be.
### Announcements appear on the side of the main page.
If you have an announcement community, each post will appear there.
`welcomemsgs` are visible on the front page when you aren't signed in.
## Other features include:
- Mods can warn users.
- Better audit logging system.
- Purging is much easier now.
- You can fucking ban people now without the Django panel.
- Each and every ban is an IP ban automatically.
- A page where every user can view collected data tied to their account.
Can you rewrite this?
# YOU NEED
- A server (obviously)
- Terminal access (also, obviously)
- Python 3
# Install time
Should probably say that this is a lazy way to do it. You should use a reverse proxy to deploy the server up for prod.
1.
SSH into your server.
2.
Time to update
`sudo apt update && sudo apt upgrade`
3.
You need Pip
`sudo apt install pip`
4.
Get everything else you need.
`pip3 install Django==3.2.2 urllib3 lxml passlib bcrypt pillow django-markdown-deux django-markdown2 whitenoise django-xff`
5.
Clone the clone!
`git clone https://github.com/Mistake35/Cedar-Django`
5.5 (recommended).
You should use FileZilla or some other SFTP client to make things easier in the future.
6.
Navigate to Cedar-Django
`cd Cedar-Django`
7.
Edit the settings.py file.
`nano closedverse/settings.py`
8.
Fill everything out as needed. Be sure to generate a secret key and paste it in too.
9.
Now it's time for the good stuff!
Let's build the database
`python3 manage.py migrate`
10.
Do the static files or no CSS or JS.
`python3 manage.py collectstatic`
11.
Test the server!
Be sure to replace "IP-HERE" with your public IP and make sure it's running on port 80.
`python3 manage.py runserver IP-HERE:80`
# Troubleshooting time!
Q: "HELP, I'M GETTING A BAD REQUEST (400) ERROR!"
A: Add your public IP to the `ALLOWED_HOSTS` bit in settings.py along with your domain that you'll be using.
Q: "django.db.utils.OperationalError: no such table: ban_usersban"
A: You forgot to migrate and make the database.
Q: "Why is the page white, with no color or style at all?"
A: You need to collect the static files as mentioned prior.
You may have to do some additional troubleshooting, and that's the joy of web-hosting.
Fixing problems yourself is a great way to learn how this shit works.
# Yet even more steps
12.
So your server is running, the URL works and everything? Good.
Now it's time to create your account.
`python3 manage.py createsuperuser`
Enter your username, and password.
13.
Make sure it's working by signing in.
14.
Alright now it's time to do some fun stuff! We're going to try and make this run at boot with systemd.
`sudo nano /etc/systemd/system/django.service`
15.
Paste this in!
Now it's time to change this if needed.
```
[Unit]
Description=Django Application
After=network.target
[Service]
User=root
WorkingDirectory=/root/Cedar-Django
ExecStart=/usr/bin/python3 manage.py runserver IP-HERE:80
[Install]
WantedBy=multi-user.target
```
16.
Pop these in!
```
sudo systemctl daemon-reload
sudo systemctl enable django
sudo systemctl start django
```
Make sure it works too!
```
sudo systemctl status django
```
+5 -1
View File
@@ -142,6 +142,10 @@ class HistoryAdmin(admin.ModelAdmin):
class RoleAdmin(admin.ModelAdmin): class RoleAdmin(admin.ModelAdmin):
exclude = ('is_static', ) exclude = ('is_static', )
class BanAdmin(admin.ModelAdmin):
# Hide that shit for now, Eventually I plan to get rid of the user_tools_meta thing completely and just show IP addresses for staff like any normal site.
exclude = ('ip_address', )
#class BlockAdmin(admin.ModelAdmin) #class BlockAdmin(admin.ModelAdmin)
admin.site.unregister(Group) admin.site.unregister(Group)
@@ -164,7 +168,7 @@ admin.site.register(models.ProfileHistory, HistoryAdmin)
admin.site.register(models.Post, PostAdmin) admin.site.register(models.Post, PostAdmin)
admin.site.register(models.Comment, CommentAdmin) admin.site.register(models.Comment, CommentAdmin)
admin.site.register(models.Ban) admin.site.register(models.Ban, BanAdmin)
admin.site.register(models.Warning) admin.site.register(models.Warning)
if settings.DEBUG: if settings.DEBUG:
+13 -8
View File
@@ -21,20 +21,25 @@ class CheckForBanMiddleware:
return response return response
def process_view(self, request, view_func, view_args, view_kwargs): def process_view(self, request, view_func, view_args, view_kwargs):
# If the user is not authenticated, there's no need to check for bans
if not request.user.is_authenticated: if not request.user.is_authenticated:
return None return None
# Get one active ban that is not expired for the user
# Get one active ban that is not expired active_user_ban = Ban.objects.filter(
active_ban = Ban.objects.filter(
to=request.user, to=request.user,
active=True, active=True,
expiry_date__gte=timezone.now() expiry_date__gte=timezone.now()
).first() ).first()
if active_user_ban:
if active_ban: return HttpResponseForbidden('You are banned from this site. Reason: ' + active_user_ban.reason)
return HttpResponseForbidden('You are banned from this site. Reason: ' + active_ban.reason) # Get one active ban that is not expired for the IP address
ip_address = request.META.get('REMOTE_ADDR')
active_ip_ban = Ban.objects.filter(
ip_address=ip_address,
active=True,
expiry_date__gte=timezone.now(),
).first()
if active_ip_ban:
return HttpResponseForbidden('Your IP address is banned from this site. Reason: ' + active_ip_ban.reason)
return None return None
class ClosedMiddleware(object): class ClosedMiddleware(object):
+7 -1
View File
@@ -207,6 +207,12 @@ class User(AbstractBaseUser):
if not g: if not g:
return settings.STATIC_URL + 'img/anonymous-mii.png' return settings.STATIC_URL + 'img/anonymous-mii.png'
return g return g
def banned(self):
banned = self.banned_user.filter(active=True, expiry_date__gt=timezone.now())
return banned.exists()
def active_ban(self):
ban = self.banned_user.filter(active=True, expiry_date__gt=timezone.now()).order_by('-created').first()
return ban
def mh(self): def mh(self):
origin_info = self.profile('origin_info') origin_info = self.profile('origin_info')
if not origin_info: if not origin_info:
@@ -582,7 +588,6 @@ class User(AbstractBaseUser):
return False return False
return user return user
# This will be a fucking pain in the ass!
class Ban(models.Model): class Ban(models.Model):
id = models.AutoField(primary_key=True) id = models.AutoField(primary_key=True)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
@@ -591,6 +596,7 @@ class Ban(models.Model):
reason = models.TextField(null=True, blank=True) reason = models.TextField(null=True, blank=True)
expiry_date = models.DateTimeField(help_text='The date and time on which this ban will expire, Set this way off into the future if this ban should be permanent') expiry_date = models.DateTimeField(help_text='The date and time on which this ban will expire, Set this way off into the future if this ban should be permanent')
active = models.BooleanField(default=True, help_text='Untick this to disable this ban') active = models.BooleanField(default=True, help_text='Untick this to disable this ban')
ip_address = models.CharField(null=True, blank=True, max_length=256, help_text='Put an IP address in here to make this an IP ban. When using the ban function outside of the Django admin panel, this is filled in automatically.')
def is_expired(self): def is_expired(self):
if timezone.now() > self.expiry_date: if timezone.now() > self.expiry_date:
@@ -1,5 +1,5 @@
{% if not post.is_rm %} {% if not post.is_rm %}
{% load closedverse_tags %}<div id="post-{{ post.id }}" {% if post.spoils and not post.is_mine or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}" class="post post-subtype-default trigger{% if post.spoils and not post.is_mine or not post.creator.is_active or post.user_is_blocked %} hidden test-hidden{% endif %}{% if type == 2 %} post-list-outline{% endif %}" tabindex="0"> {% load closedverse_tags %}<div id="post-{{ post.id }}" {% if post.spoils and not post.is_mine or post.creator.banned %}data-href-hidden{% else %}data-href{% endif %}="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}" class="post post-subtype-default trigger{% if post.spoils and not post.is_mine or post.creator.banned or post.user_is_blocked %} hidden test-hidden{% endif %}{% if type == 2 %} post-list-outline{% endif %}" tabindex="0">
{% if with_community_container %} {% if with_community_container %}
<p class="community-container"> <p class="community-container">
{% if post.is_reply %} {% if post.is_reply %}
@@ -15,9 +15,6 @@
<span class="owner-label">Community Owner</span> <span class="owner-label">Community Owner</span>
{% endif %} {% endif %}
<p class="user-name"><a href="{% url "main:user-view" post.creator.username %}"{% if post.creator.color %}style=color:{{ post.creator.color }}{% endif %}>{{ post.creator.nickname }}</a></p> <p class="user-name"><a href="{% url "main:user-view" post.creator.username %}"{% if post.creator.color %}style=color:{{ post.creator.color }}{% endif %}>{{ post.creator.nickname }}</a></p>
{% if not post.creator.is_active %}
<p style="color: #f00;">Banned</p>
{% endif %}
<p class="timestamp-container"> <p class="timestamp-container">
<span class="spoiler-status{% if post.spoils %} spoiler{% endif %}">Spoilers·</span> <span class="spoiler-status{% if post.spoils %} spoiler{% endif %}">Spoilers·</span>
{% if post.has_edit %} {% if post.has_edit %}
@@ -45,15 +42,15 @@
{% endif %} {% endif %}
{% if post.screenshot %}<a class="screenshot-container still-image" href="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}"><img src="{{ post.screenshot }}"></a>{% endif %} {% if post.screenshot %}<a class="screenshot-container still-image" href="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}"><img src="{{ post.screenshot }}"></a>{% endif %}
{% if post.video %}<div class="screenshot-container still-image"><video class="vidya" controls src="{{ post.video }}" style="max-width:100%;max-height: 450px;"></video></div>{% endif %} {% if post.video %}<div class="screenshot-container still-image"><video class="vidya" controls src="{{ post.video }}" style="max-width:100%;max-height: 450px;"></video></div>{% endif %}
{% if post.spoils and not post.is_mine and post.creator.is_active %} {% if post.spoils and not post.is_mine and not post.creator.banned %}
<div class="hidden-content"><p>This post contains spoilers.</p> <div class="hidden-content"><p>This post contains spoilers.</p>
<button type="button" class="hidden-content-button">View Post</button> <button type="button" class="hidden-content-button">View Post</button>
</div> </div>
{% endif %} {% endif %}
{% if not post.creator.is_active %} {% if post.creator.banned %}
<div class="hidden-content"><p>Content hidden because its creator was banned. </p> <div class="hidden-content"><p>Content hidden because {{ post.creator.username }} was banned. </p>
{% if post.creator.get_warned_reason %} {% if post.creator.active_ban %}
<p>Reason: {{post.creator.get_warned_reason}} <p>Reason: {{post.creator.active_ban.reason }}
{% endif %} {% endif %}
<button type="button" class="hidden-content-button">View Anyway</button> <button type="button" class="hidden-content-button">View Anyway</button>
</p></div> </p></div>
@@ -74,7 +71,7 @@
<div class="reply symbol"><span class="symbol-label">Comments</span><span class="reply-count">{{ post.number_comments }}</span></div> <div class="reply symbol"><span class="symbol-label">Comments</span><span class="reply-count">{{ post.number_comments }}</span></div>
{% endif %} {% endif %}
</div> </div>
{% if post.recent_comment and post.recent_comment.creator.is_active %} {% if post.recent_comment and not post.recent_comment.creator.banned %}
<div class="recent-reply-content"> <div class="recent-reply-content">
{% if post.number_comments > 1 %} {% if post.number_comments > 1 %}
<div class="recent-reply-read-more-container" tabindex="0"> <div class="recent-reply-read-more-container" tabindex="0">
@@ -1,11 +1,8 @@
{% if not comment.is_rm %}{% load closedverse_tags %}<li id="comment-{{ comment.id }}" {% if comment.spoils and not comment.is_mine or not comment.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:comment-view" comment.id %}" class="post {% if comment.owner_post %}my{% else %}other{% endif %}{% if comment.spoils and not comment.is_mine or not comment.creator.is_active %} hidden{% endif %} trigger"> {% if not comment.is_rm %}{% load closedverse_tags %}<li id="comment-{{ comment.id }}" {% if comment.spoils and not comment.is_mine or comment.creator.banned %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:comment-view" comment.id %}" class="post {% if comment.owner_post %}my{% else %}other{% endif %}{% if comment.spoils and not comment.is_mine or comment.creator.banned %} hidden{% endif %} trigger">
{% user_icon_container comment.creator comment.feeling %} {% user_icon_container comment.creator comment.feeling %}
<div class="body"> <div class="body">
<div class="header"> <div class="header">
<p class="user-name"><a {% if comment.creator.color %}style=color:{{ comment.creator.color }}{% endif %} href="{% url "main:user-view" comment.creator.username %}">{{ comment.creator.nickname }}</a></p> <p class="user-name"><a {% if comment.creator.color %}style=color:{{ comment.creator.color }}{% endif %} href="{% url "main:user-view" comment.creator.username %}">{{ comment.creator.nickname }}</a></p>
{% if not comment.creator.is_active %}
<p style="color: #f00;">Banned</p>
{% endif %}
<p class="timestamp-container"> <p class="timestamp-container">
<a class="timestamp" {% if comment.spoils and not comment.is_mine %}data-href-hidden{% else %}href{% endif %}="{% url "main:comment-view" comment.id %}">{% time comment.created %}</a> <a class="timestamp" {% if comment.spoils and not comment.is_mine %}data-href-hidden{% else %}href{% endif %}="{% url "main:comment-view" comment.id %}">{% time comment.created %}</a>
{% if comment.drawing %} {% if comment.drawing %}
@@ -26,15 +23,15 @@
{% if comment.screenshot %} {% if comment.screenshot %}
<div class="screenshot-container still-image"><img src="{{ comment.screenshot }}"></div> <div class="screenshot-container still-image"><img src="{{ comment.screenshot }}"></div>
{% endif %} {% endif %}
{% if comment.spoils and not comment.is_mine and comment.creator.is_active %} {% if comment.spoils and not comment.is_mine and not comment.creator.banned %}
<div class="hidden-content"><p>This comment contains spoilers.</p> <div class="hidden-content"><p>This comment contains spoilers.</p>
<button type="button" class="hidden-content-button">View Comment</button> <button type="button" class="hidden-content-button">View Comment</button>
</div> </div>
{% endif %} {% endif %}
{% if not comment.creator.is_active %} {% if comment.creator.banned %}
<div class="hidden-content"><p>Content hidden because its creator was banned. </p> <div class="hidden-content"><p>Content hidden because {{ comment.creator.username }} was banned. </p>
{% if comment.creator.get_warned_reason %} {% if comment.creator.active_ban %}
<p>Reason: {{comment.creator.get_warned_reason}} <p>Reason: {{comment.creator.active_ban.reason }}
{% endif %} {% endif %}
<button type="button" class="hidden-content-button">View Anyway</button> <button type="button" class="hidden-content-button">View Anyway</button>
</p></div> </p></div>
@@ -1,4 +1,4 @@
{% load closedverse_tags %}<div {% if post.spoils and not post.is_mine or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:post-view" post.id %}" class="post trigger{% if post.screenshot and not for_announcements %} with-image{% endif %}{% if post.spoils and not post.is_mine or not post.creator.is_active %} hidden test-hidden{% endif %}" tabindex="0"> {% load closedverse_tags %}<div {% if post.spoils and not post.is_mine or post.creator.banned %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:post-view" post.id %}" class="post trigger{% if post.screenshot and not for_announcements %} with-image{% endif %}{% if post.spoils and not post.is_mine or post.creator.banned %} hidden test-hidden{% endif %}" tabindex="0">
<p class="community-container"><a {% if post.community.clickable %}href="{% url "main:community-view" post.community_id %}"{% endif %}><img src="{{ post.community.icon }}" class="community-icon">{{ post.community.name }}</a></p> <p class="community-container"><a {% if post.community.clickable %}href="{% url "main:community-view" post.community_id %}"{% endif %}><img src="{{ post.community.icon }}" class="community-icon">{{ post.community.name }}</a></p>
@@ -40,15 +40,15 @@
<p class="post-content-text">{{ post.body|truncatechars:100|linebreaksbr }}</p> <p class="post-content-text">{{ post.body|truncatechars:100|linebreaksbr }}</p>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if post.spoils and not post.is_mine and post.creator.is_active %} {% if post.spoils and not post.is_mine and not post.creator.banned %}
<div class="hidden-content"><p>This post contains spoilers. <div class="hidden-content"><p>This post contains spoilers.
<button type="button" class="hidden-content-button">View Post</button> <button type="button" class="hidden-content-button">View Post</button>
</p></div> </p></div>
{% endif %} {% endif %}
{% if not post.creator.is_active %} {% if post.creator.banned %}
<div class="hidden-content"><p>Content hidden because its creator was banned. </p> <div class="hidden-content"><p>Content hidden because {{ post.creator.username }} was banned. </p>
{% if post.creator.get_warned_reason %} {% if post.creator.active_ban %}
<p>Reason: {{post.creator.get_warned_reason}} <p>Reason: {{post.creator.active_ban.reason }}
{% endif %} {% endif %}
<button type="button" class="hidden-content-button">View Anyway</button> <button type="button" class="hidden-content-button">View Anyway</button>
</p></div> </p></div>
@@ -1,12 +1,12 @@
{% load closedverse_tags %}{% load closedverse_user %} {% load closedverse_tags %}{% load closedverse_user %}
{% if user.is_authenticated %}<div id="sidebar" class="{% if general %}general{% else %}user{% endif %}-sidebar"> {% if user.is_authenticated %}<div id="sidebar" class="{% if general %}general{% else %}user{% endif %}-sidebar">
{% if not user.is_active %} {% if user.banned %}
<div class="notice" style="background-color: #ff9797;border: 1px solid #ff5252;"> <div class="notice" style="background-color: #ff9797;border: 1px solid #ff5252;">
<b>Notice</b>: This user account is disabled. <b>Notice</b>: This user is banned.
<div> <div>
{% if user.get_warned_reason %} {% if user.active_ban.reason %}
<p>Reason: "{{ user.get_warned_reason }}"</p> <p>Reason: "{{ user.active_ban.reason }}"</p>
{% endif %} {% endif %}
</div> </div>
</div> </div>
+4 -10
View File
@@ -1743,13 +1743,6 @@ def user_tools_bams(request, username):
user = get_object_or_404(User, username__iexact=username) user = get_object_or_404(User, username__iexact=username)
profile = user.profile() profile = user.profile()
profile.setup(request) profile.setup(request)
active_bans = user.banned_user.filter(active=True).exclude(expiry_date__lte=timezone.now())
if active_bans:
banned = True
active_ban = active_bans.first()
else:
banned = False
active_ban = None
if not request.user.can_manage(): if not request.user.can_manage():
return HttpResponseForbidden() return HttpResponseForbidden()
if user.has_authority(request.user): if user.has_authority(request.user):
@@ -1760,15 +1753,16 @@ def user_tools_bams(request, username):
ban = form.save(commit=False) ban = form.save(commit=False)
ban.to = user ban.to = user
ban.by = request.user ban.by = request.user
ban.ip_address = user.addr
ban.save() ban.save()
return redirect('main:user-view', user) return redirect('main:user-view', user)
if not banned: if not user.banned():
form = Give_Ban_Form() form = Give_Ban_Form()
else: form = None else: form = None
return render(request, 'closedverse_main/man/manage_bans.html', { return render(request, 'closedverse_main/man/manage_bans.html', {
'user': user, 'user': user,
'banned': banned, 'banned': user.banned(),
'active_ban': active_ban, 'active_ban': user.active_ban(),
'profile': profile, 'profile': profile,
'form': form, 'form': form,
}) })