Commits

Luke Plant  committed 7251c11 Merge

Merged from default

  • Participants
  • Parent commits 80e1873, 21267df
  • Branches live

Comments (0)

Files changed (11)

File cciw/auth.py

+WIKI_USERS_GROUP_NAME = 'Wiki users'
+SECRETARY_GROUP_NAME = 'Secretaries'
+OFFICER_GROUP_NAME = 'Officers'
+LEADER_GROUP_NAME = 'Leaders'
+
+
+def is_camp_admin(user):
+    """
+    Returns True if the user is an admin for any camp, or has rights
+    for editing camp/officer/reference/CRB information
+    """
+    return (user.groups.filter(name=LEADER_GROUP_NAME) |
+            user.groups.filter(name=SECRETARY_GROUP_NAME)).exists() \
+        or user.camps_as_admin.exists() > 0
+
+
+def is_wiki_user(user):
+    return user.groups.filter(name=WIKI_USERS_GROUP_NAME).exists()
+
+
+def is_cciw_secretary(user):
+    return user.groups.filter(name=SECRETARY_GROUP_NAME).exists()
+
+
+def is_camp_officer(user):
+    return (user.groups.filter(name=OFFICER_GROUP_NAME) |
+            user.groups.filter(name=LEADER_GROUP_NAME)).exists()
+

File cciw/cciwmain/static/css/djiki.css

+
+/* Djiki styles */
+.djiki {
+}
+	.djiki .actions {
+	}
+		.djiki .actions ul {
+			list-style-type: none;
+			margin: 0 10px 0 10px;
+			padding: 0;
+			float: right;
+		}
+			.djiki .actions ul li {
+				display: inline;
+				border-left: 1px solid lightGray;
+				border-top: 1px solid lightGray;
+				border-right: 1px solid lightGray;
+			}
+				.djiki .actions ul li a {
+					padding: 3px 10px;
+				}
+	.djiki .page {
+		border: 1px solid lightGray;
+	}
+		.djiki .page .content {
+			margin: 10px;
+		}
+		.djiki .page .editForm fieldset {
+			margin: 0;
+			padding: 0;
+		}
+			.djiki .page .editForm fieldset .label {
+				text-align: left;
+			}
+				.djiki .page .editForm fieldset .label label {
+					font-weight: bold;
+				}
+			.djiki .page .editForm fieldset .field input,
+			.djiki .page .editForm fieldset .field textarea {
+				width: 840px;
+			}
+			.djiki .page .editForm fieldset .field textarea {
+				min-height: 360px;
+			}
+			.djiki .page .editForm .buttons {
+				padding: 10px 0;
+			}
+				.djiki .page .editForm .buttons button.save {
+					font-weight: bold;
+				}
+
+.djiki #messages ul {
+	list-style-type: none;
+	margin: 0 0 10px 0;
+	padding: 0 15px;
+}
+	.djiki #messages ul li {
+		border-width: 1px 1px 1px 5px;
+		border-style: solid;
+		border-color: #8f8;
+		background-color: #efe;
+		margin: 3px 0;
+		padding: 5px 10px;
+	}
+		.djiki #messages ul li.warning {
+			background-color: #fee;
+			border-color: #f88;
+		}
+
+.djiki .help_text {
+	font-size: 75%;
+	color: #444;
+}
+
+/* styles for history screen */
+.djiki .page.history .content table {
+	border-collapse: collapse;
+}
+	.djiki .page.history .content table tr {
+	}
+		.djiki .page.history .content table th, .djiki .page.history .content table td {
+			padding: 1px 10px;
+			border: 1px solid #eee;
+		}
+
+.djiki .page.diff .content .diff {
+	padding: 10px 20px;
+	background-color: #eee;
+}
+	.djiki .page.diff .content .diff .added {
+		background-color: #8f8;
+	}
+	.djiki .page.diff .content .diff .removed {
+		background-color: #f88;
+	}
+
+/* styles used inside the page contents - might me moved to a separate file */
+.djiki .page .content .image {
+	border: 1px solid #e0e0e0;
+	background: #f0f0f0;
+	margin: 10px 0;
+	padding: 3px;
+	float: left;
+}
+.djiki .page .content .image.with_size,
+.djiki .page .content .image.external {
+	margin-right: 10px;
+}
+	.djiki .page .content .image .title {
+		margin: 5px 0;
+		padding: 0;
+		font-size: 80%;
+	}

File cciw/middleware/auth.py

+from django.http import HttpResponseForbidden
+from django.utils.html import escape
+from django.utils.http import urlquote
+from django.conf import settings
+
+from cciw.auth import is_wiki_user
+
+class PrivateWiki(object):
+    # Make the wiki restricted to logged in users only.  Djiki does not provide
+    # this feature yet.
+    def process_request(self, request):
+        if request.path.startswith('/wiki/'):
+            if not (hasattr(request, 'user') and
+                    request.user.is_authenticated()):
+                return HttpResponseForbidden("<h1>Forbidden</h1>"
+                                             "<p>You must be <a href='%s?next=%s'>logged in</a> to use this.</p>" %
+                                             (settings.LOGIN_URL, escape(urlquote(request.get_full_path()))))
+            if not is_wiki_user(request.user):
+                return HttpResponseForbidden("<h1>Forbidden</h1>"
+                                             "<p>You do not have permission to access the wiki.</p>")
+

File cciw/officers/views.py

 from django.views.decorators.cache import never_cache
 from django.views.generic.base import TemplateView
 
+from cciw.auth import is_camp_admin, is_wiki_user, is_cciw_secretary, is_camp_officer
 from cciw.cciwmain import common
 from cciw.cciwmain.decorators import json_response
 from cciw.cciwmain.models import Camp
     return new_obj
 
 
-SECRETARY_GROUP_NAME = 'Secretaries'
-LEADER_GROUP_NAME = 'Leaders'
-
-def _is_camp_admin(user):
-    """
-    Returns True if the user is an admin for any camp, or has rights
-    for editing camp/officer/reference/CRB information
-    """
-    return (user.groups.filter(name=LEADER_GROUP_NAME) |
-            user.groups.filter(name=SECRETARY_GROUP_NAME)).exists() \
-        or user.camps_as_admin.exists() > 0
-
-
 def user_passes_test_improved(test_func):
     """
     Like user_passes_test, but doesn't redirect user to login screen if they are
     return decorator
 
 
-camp_admin_required = user_passes_test_improved(_is_camp_admin)
+camp_admin_required = user_passes_test_improved(is_camp_admin)
 
 
-def _is_cciw_secretary(user):
-    return user.groups.filter(name=SECRETARY_GROUP_NAME).exists()
-
-
-def _is_camp_officer(user):
-    return user.is_authenticated() and \
-        (user.groups.filter(name='Officers') |
-         user.groups.filter(name='Leaders')).exists()
-
 
 def _camps_as_admin_or_leader(user):
     """
     user = request.user
     c = {}
     c['thisyear'] = common.get_thisyear()
-    if _is_camp_admin(user):
+    if is_camp_admin(user):
         c['show_leader_links'] = True
         c['show_admin_link'] = True
-    if _is_cciw_secretary(user):
+    if is_cciw_secretary(user):
         c['show_secretary_links'] = True
         c['show_admin_link'] = True
 
         raise Http404
 
     if app.officer_id != request.user.id and \
-            not _is_camp_admin(request.user):
+            not is_camp_admin(request.user):
         raise PermissionDenied
 
     # NB, this is is called by both normal users and leaders.
 
 
 officer_files = access_folder_securely("officers",
-                                       lambda request: _is_camp_officer(request.user))
+                                       lambda request: request.user.is_authenticated() and is_camp_officer(request.user))
 
 
 def date_to_js_ts(d):
     return render(request, 'cciw/officers/crb_consent_problem.html', c)
 
 
-officer_info = staff_member_required(TemplateView.as_view(template_name='cciw/officers/info.html'))
+class OfficerInfo(TemplateView):
+    template_name='cciw/officers/info.html'
+    def get_context_data(self, *args, **kwargs):
+        return dict(show_wiki_link=is_wiki_user(self.request.user))
+
+
+officer_info = staff_member_required(OfficerInfo.as_view())

File cciw/settings.py

     'mailer',
     'securedownload',
     'autocomplete',
+    'djiki',
 )
 
 if not (LIVEBOX and WEBSERVER_RUNNING):
     (True,       "django.contrib.messages.middleware.MessageMiddleware"),
     (True,       "django.contrib.auth.middleware.AuthenticationMiddleware"),
     (True,       "django.middleware.common.CommonMiddleware"),
+    (True,       "cciw.middleware.auth.PrivateWiki"),
     (True,       "django.middleware.transaction.TransactionMiddleware"),
     (True,       "cciw.middleware.threadlocals.ThreadLocals"),
 )
 
 FILE_UPLOAD_MAX_MEMORY_SIZE = 262144
 
+#####  DJIKI  ######
+
+DJIKI_IMAGES_PATH = 'wiki/images/'
+DJIKI_ALLOW_ANONYMOUS_EDITS = False
+
+####################
+
 ## CCIW SPECIFIC SETTINGS AND CONSTANTS
 AWARD_UPLOAD_PATH = 'images/awards'
 MEMBER_ICON_UPLOAD_PATH = 'images/members/temp'

File cciw/urls.py

 from django.contrib import admin
 from django.contrib.auth.models import User
 
-import cciw.officers.views
+import cciw.auth
 
 handler404 = 'cciw.cciwmain.views.handler404'
 
     fields=('first_name__istartswith', 'last_name__istartswith'),
     limit=10,
     label=lambda user: "%s %s <%s>" % (user.first_name, user.last_name, user.email),
-    auth=lambda request: request.user.is_authenticated() and cciw.officers.views._is_camp_admin(request.user)
+    auth=lambda request: request.user.is_authenticated() and cciw.auth.is_camp_admin(request.user)
     )
 
 urlpatterns = patterns('',
     (r'^admin/', include(admin.site.urls)),
     (r'^officers/', include('cciw.officers.urls')),
     url('^autocomplete/(\w+)/$', autocomplete, name='autocomplete'),
+    (r'wiki/', include('djiki.urls')),
 
 )
 

File requirements.txt

 south==0.7.2
 xlwt==0.7.2
 xlrd==0.7.1
+creole>=1.2
 

File templates/cciw/officers/info.html

 <ul>
 <li><a href="{% url 'cciw.officers.views.officer_files' 'CCIW CPP.doc' %}">The
     camp manual and child protection policy</a></li>
+{% if show_wiki_link %}
+  <li><a href="/wiki/Index">CCIW wiki</a></li>
+{% endif %}
 </ul>
 
 {% endblock %}

File templates/djiki/base.html

+{% extends 'cciw/officers/base.html' %}
+{% load static %}
+{% block title %}
+CCIW Officer wiki
+{% endblock %}
+{% block extrastyle %}{{ block.super }}
+<link rel="stylesheet" type="text/css" href="{% static "css/djiki.css" %}" />
+{% endblock %}
+
+{% block userlinks %}<a href="/officers/">Officer homepage</a> / <a href="/wiki/Index">Wiki start</a>{% endblock %}
+{% block content %}
+<div class="djiki">
+	<div class="actions">
+		<div>
+		{% block djiki_actions %}{% endblock %}
+		</div>
+		<div class="clear"></div>
+	</div>
+	<div class="main">
+		{% block djiki_main %}{% endblock %}
+		<div class="clear"></div>
+	</div>
+</div>
+{% endblock %}

File templates/djiki/image_view.html

+{% extends 'djiki/base_image.html' %}
+{% block djiki_main %}
+<div class="page content">
+	<div class="content">
+		<h1>{{ image.name }}</h1>
+		<a href="{{ image.last_revision.file.url }}"><img src="{{ image.last_revision.file.url }}" alt="{{ image.name }}" /></a>
+	</div>
+</div>
+{% endblock %}

File templates/djiki/parser/image.html

+<div class="image{% if not image %} external{% endif %}">
+	{% if image %}
+	<a href="{% url djiki-image-view url_name %}">
+          <img src="{{ image.last_revision.file.url }}" alt="{{ title }}" />
+	</a>
+	{% else %}
+	<img src="{{ url }}" alt="{{ title }}" />
+	{% endif %}
+	{% if title %}
+	<p class="title">{{ title }}</p>
+	{% endif %}
+</div>