Skip to content

Commit

Permalink
# This is a combination of 11 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

wooo

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #2:

moving computers

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #3:

v1 complete

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #4:

documentation

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #5:

code cleanup and minor bug fixes

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #6:

progress

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #7:

finish feature

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #8:

cleanup and help text

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #9:

working wiki integration

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #10:

wiki branding

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>

# This is the commit message #11:

documentation

Signed-off-by: Joe Kaufeld <joe.kaufeld@gmail.com>
  • Loading branch information
Joe Kaufeld committed May 14, 2021
1 parent f9917a9 commit cec5500
Show file tree
Hide file tree
Showing 16 changed files with 407 additions and 29 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,4 @@ venv.bak/
static/
.idea/*
*/migrations/*
*/media/wiki/*
36 changes: 27 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ better_exceptions.MAX_LENGTH = None
# change how the server runs.

DEBUG = True
# this requires that you use "grafeas.localhost:8000" as your method for accessing
# the site.
# ALLOWED_HOSTS = ['.grafeas.localhost', 'grafeas.localhost', 'wiki.grafeas.localhost']
ALLOWED_HOSTS = ['*']
SESSION_COOKIE_DOMAIN = "grafeas.localhost"
PARENT_HOST = 'grafeas.localhost:8000'

CACHES = {
'default': {
Expand All @@ -38,8 +43,17 @@ DATABASES = {
}
```

## Notes on URLs

Because there are subdomains that share a common session cookie, using `localhost:8000` as the development URL isn't an option because of some legacy issues with how the internet works. In Chrome, ending any URL with `.localhost` will automatically loop back to the host computer, so you don't have to modify your `hosts` file. Make sure that when you're working with the application, you're using `grafeas.localhost:8000` as the base url; for example, `wiki.grafeas.localhost:8000` or `payments.grafeas.localhost:8000`. This will translate to `grafeas.org` when deployed, so verify that anything that needs to be cross-subdomain is able to tell what the base host is.


* Minimum Python version: 3.8

* In order to get the wiki to work, there are some extra system dependencies that need to be installed.
* OSX: Download and install this: `http://ethan.tira-thompson.com/Mac_OS_X_Ports_files/libjpeg-libpng%20%28universal%29.dmg` (more information here: https://django-wiki.readthedocs.io/en/latest/installation.html#mac-os-x-10-5)
* Debian / Ubuntu: `sudo apt-get install libjpeg8 libjpeg-dev libpng12-0 libpng12-dev`

* Install dependencies with `poetry install`. Don't have Poetry? Info here: https://poetry.eustace.io/

* Run `python manage.py makemigrations blossom` to build the migrations, then commit them to the database with `python manage.py migrate --settings=blossom.local_settings`.
Expand All @@ -50,11 +64,11 @@ DATABASES = {
* password: `asdf`

You can use the above credentials to create yourself a new account.
* Navigate to http://localhost:8000/superadmin/newuser and log in with the above credentials.
* Navigate to http://grafeas.localhost:8000/superadmin/newuser and log in with the above credentials.
* Create a personal user account with the requested fields. Make sure that you select "is superuser".

Next, we'll disable the default admin account.
* Navigate to http://localhost:8000/superadmin/blossom/blossomuser/ and click on the "admin" user.
* Navigate to http://grafeas.localhost:8000/superadmin/blossom/blossomuser/ and click on the "admin" user.
* Scroll to the bottom of the page and deselect "Active".
* Click Save.

Expand All @@ -76,30 +90,34 @@ Run `python manage.py bootstrap` and see above for expected user credentials and

## Important links

#### payments.localhost:8000
#### payments.grafeas.localhost:8000

The processing url for Stripe.

#### payments.localhost:8000/ping
#### payments.grafeas.localhost:8000/ping

Used by Bubbles for site isup checks.

#### localhost:8000
#### grafeas.localhost:8000

Site root.

#### localhost:8000/admin/
#### grafeas.localhost:8000/admin/

General site administration, open to all user accounts.

#### localhost:8000/superadmin/
#### grafeas.localhost:8000/superadmin/

User / post traditional admin. Requires staff acount.

#### localhost:8000/superadmin/newuser
#### grafeas.localhost:8000/superadmin/newuser

Create a new user for the site.

#### localhost:8000/newpost
#### grafeas.localhost:8000/newpost

Create a new post for the site.

#### wiki.grafeas.localhost:8000/

Root for wiki.
9 changes: 9 additions & 0 deletions blossom/.env.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
POSTGRES_USER=blossom_app
POSTGRES_PASSWORD=asdfasdfasdf
POSTGRES_DB=blossom

REDDIT_CLIENT_ID=jmeW7q3nt6NeSg
REDDIT_SECRET=ebBPZ2RNDaVzbBHHuk4xpyJTffU
REDDIT_USERNAME=blossom-app
REDDIT_PASSWORD=60pNPq0E%J$htOC!49UZ
REDDIT_USER_AGENT="Blossom:/r/transcribersofreddit. Contact /u/itsthejoker"
1 change: 0 additions & 1 deletion blossom/authentication/custom_auth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend


# https://stackoverflow.com/a/37332393
class EmailBackend(ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion blossom/authentication/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.urls import path

from blossom.website.views import LoginView, LogoutView
from blossom.authentication.views import LoginView, LogoutView

urlpatterns = [
path('login/', LoginView.as_view(), name='login'),
Expand Down
78 changes: 78 additions & 0 deletions blossom/authentication/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from django.contrib.auth import login, logout
from django.shortcuts import render, HttpResponseRedirect
from django.urls import resolve
from django.urls.exceptions import Resolver404, NoReverseMatch
from django.urls.resolvers import get_resolver
from django.views.generic import TemplateView
from django_hosts.resolvers import get_host_patterns, reverse

from blossom.authentication.custom_auth import EmailBackend
from blossom.website.forms import LoginForm


class LoginView(TemplateView):

def get_redirect(self, request, hosts):
# work around a super obnoxious problem with django-hosts where if it
# doesn't find the url that you're looking for in the default host,
# it just gives up. This will allow us to cycle through the hosts and
# try to find one that returns a ResolverMatch.

# first let's see if the requested url DOES resolve in the base host.
nextpath = request.GET['next']
try:
match = resolve(nextpath)
try:
return reverse(match.view_name)
except NoReverseMatch:
pass
except Resolver404:
pass

for h in hosts:
try:
match = get_resolver(h.urlconf).resolve(nextpath)
try:
return reverse(match.view_name, host=match.namespace)
except NoReverseMatch:
continue
except Resolver404:
continue

# still haven't found a match? The only thing left is that it's really
# borked or it's a full url to something like the wiki.
if nextpath.endswith(
request.get_host()
) or nextpath.endswith(
request.get_host() + '/'
):
return nextpath

raise Resolver404

def get(self, request, *args, **kwargs):
form = LoginForm()
return render(request, 'website/generic_form.html', {'form': form})

def post(self, request, *args, **kwargs):
form = LoginForm(request.POST)
if form.is_valid():
data = form.cleaned_data
if user := EmailBackend().authenticate(
username=data.get('email'), password=data.get('password')
):
login(request, user)

if request.GET.get('next', None):
hosts = get_host_patterns()
location = self.get_redirect(request, hosts)
else:
location = '/'

return HttpResponseRedirect(location)
return HttpResponseRedirect('/')


def LogoutView(request):
logout(request)
return HttpResponseRedirect('/')
3 changes: 2 additions & 1 deletion blossom/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
host(r'api', 'blossom.api.urls', name='api'),
host(r'payments', 'blossom.payments.urls', name='payments'),
host(r'engineering', 'blossom.engineeringblog.urls', name='engineeringblog'),
host(r'', settings.ROOT_URLCONF, name='www')
host(r'wiki', 'blossom.wiki.urls', name='wiki'),
host(r'', settings.ROOT_URLCONF, name='www'), # must always be last
)
1 change: 1 addition & 0 deletions blossom/media/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This folder is used by the wiki to hold user-uploaded content.
48 changes: 38 additions & 10 deletions blossom/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import os

from django_hosts.resolvers import reverse_lazy

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Expand All @@ -24,23 +26,36 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['.grafeas.org', 'grafeas.org']
# force cross-domain cookies so that wiki login can use the regular login page
ALLOWED_HOSTS = ['.grafeas.org/', 'grafeas.org/']
SESSION_COOKIE_DOMAIN = 'grafeas.org'

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static_dev')
]

LOGIN_URL = "/login/"
LOGIN_URL = reverse_lazy("login", host='www')
LOGOUT_URL = reverse_lazy("logout", host='www')

# for subdomain routing
ROOT_HOSTCONF = 'blossom.hosts'
DEFAULT_HOST = 'www'
if DEBUG:
PARENT_HOST = 'localhost:8000'
else:
PARENT_HOST = 'grafeas.org'
PARENT_HOST = 'grafeas.org'

# wiki
WIKI_ACCOUNT_HANDLING = False
# ideally, we would handle this with the following line:
# WIKI_ANONYMOUS = False
# but if we do, then the forced login redirects with a `next` parameter of '/',
# which of course sends us back to the regular site instead of the proper
# subdomain. Perhaps something to look into in the future.
# todo: fix anonymous handling

# Application definition

Expand All @@ -53,6 +68,19 @@
'django.contrib.staticfiles',
'django_hosts',
'widget_tweaks',
# wiki
'django.contrib.sites.apps.SitesConfig',
'django.contrib.humanize.apps.HumanizeConfig',
'django_nyt.apps.DjangoNytConfig',
'mptt',
'sekizai',
'sorl.thumbnail',
'wiki.apps.WikiConfig',
'wiki.plugins.attachments.apps.AttachmentsConfig',
# todo: this is super broken for some reason
# 'wiki.plugins.notifications.apps.NotificationsConfig',
'wiki.plugins.images.apps.ImagesConfig',
'wiki.plugins.macros.apps.MacrosConfig',
'blossom',
]

Expand All @@ -67,6 +95,7 @@
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'blossom.wiki.middleware.wiki_media_url_rewrite',
'django_hosts.middleware.HostsResponseMiddleware',
]

Expand All @@ -77,6 +106,7 @@
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'templates', 'wiki')
],
'APP_DIRS': True,
'OPTIONS': {
Expand All @@ -85,6 +115,7 @@
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'sekizai.context_processors.sekizai',
],
},
},
Expand Down Expand Up @@ -137,7 +168,4 @@

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'
SITE_ID = 1
19 changes: 19 additions & 0 deletions blossom/templates/wiki/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends "wiki/base_site.html" %}
{% load hosts %}

{% block wiki_site_title %} - Wiki{% endblock %}

{% block wiki_header_branding %}
<a class="navbar-brand" href="/">Grafeas Group, Ltd.</a>
{% endblock %}

{% block wiki_header_navlinks %}
<ul class="nav navbar-nav">
<li class="active"><a href="{% url 'wiki:root' %}">Wiki</a></li>
</ul>
<ul class="nav navbar-nav">
<li>
<a href="{% host_url 'homepage' host 'www' %}">Home</a>
</li>
</ul>
{% endblock %}
6 changes: 4 additions & 2 deletions blossom/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
from django.contrib import admin
from django.urls import path

from blossom.authentication.custom_user import BlossomUser
from blossom.authentication.views import LoginView
from blossom.website.models import Post
from blossom.website.urls import urlpatterns as website_urls
from blossom.authentication.custom_user import BlossomUser
from blossom.website.views import LoginView, user_create
from blossom.website.views import user_create

admin.autodiscover()
admin.site.login = LoginView.as_view()
Expand All @@ -38,3 +39,4 @@

if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
14 changes: 10 additions & 4 deletions blossom/website/views.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth import login, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.shortcuts import render, HttpResponseRedirect, redirect
from django.utils.decorators import method_decorator
from django.views.generic import DetailView, UpdateView
from django.views.generic import TemplateView

from blossom.authentication.custom_auth import EmailBackend
from blossom.website.forms import LoginForm, PostAddForm, AddUserForm
from blossom.website.forms import PostAddForm, AddUserForm
from blossom.website.helpers import get_additional_context
from blossom.website.models import Post

Expand Down Expand Up @@ -50,6 +47,15 @@ def LogoutView(request):
return HttpResponseRedirect('/')


class PostView(TemplateView):

def get(self, request, *args, **kwargs):
pass

def post(self, request, *args, **kwargs):
pass


class PostDetail(DetailView):
model = Post
query_pk_and_slug = True
Expand Down

0 comments on commit cec5500

Please sign in to comment.