summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@dev.spline.de>2008-08-17 12:08:12 +0200
committerroot <root@dev.spline.de>2008-08-17 12:08:12 +0200
commit236ad4c8dbef414ef29348634fd0a6ccded1a1d6 (patch)
treeb41990232be2235d87878c8f35fbc4a55b8448dc
downloaddev-account-236ad4c8dbef414ef29348634fd0a6ccded1a1d6.tar.gz
dev-account-236ad4c8dbef414ef29348634fd0a6ccded1a1d6.tar.xz
dev-account-236ad4c8dbef414ef29348634fd0a6ccded1a1d6.zip
initial import
-rw-r--r--TODO4
-rw-r--r--__init__.py0
-rw-r--r--index.py367
-rw-r--r--settings.py3
-rw-r--r--templates/.index.html.swpbin0 -> 12288 bytes
-rw-r--r--templates/activation_mail.txt13
-rw-r--r--templates/base.html95
-rw-r--r--templates/deleted_project_mail.txt11
-rw-r--r--templates/imprint.html29
-rw-r--r--templates/index.html17
-rw-r--r--templates/members.html37
-rw-r--r--templates/new_project.html35
-rw-r--r--templates/new_project_mail.txt15
-rw-r--r--templates/password.html19
-rw-r--r--templates/password_mail.txt12
-rw-r--r--templates/profile.html35
-rw-r--r--templates/projects.html53
-rw-r--r--templates/register.html40
-rw-r--r--templates/registration_mail.txt11
19 files changed, 796 insertions, 0 deletions
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..d681c03
--- /dev/null
+++ b/TODO
@@ -0,0 +1,4 @@
+* mailing listen
+* upload backup and send links
+* send mail to dev@spline.de on errors
+* bugs, bugs, bugs
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/__init__.py
diff --git a/index.py b/index.py
new file mode 100644
index 0000000..813e79b
--- /dev/null
+++ b/index.py
@@ -0,0 +1,367 @@
+# setup django environment, so we can use their template engine
+from django.core.management import setup_environ
+from account import settings
+setup_environ(settings)
+
+from django.template import Context
+from django.template.loader import render_to_string
+
+# mod_python session handling and redirects
+from mod_python import Session
+from mod_python.util import redirect
+
+# import mysql bindings
+import MySQLdb
+
+# import other common stuff
+from random import choice
+import base64, cracklib, sha, string, os
+
+
+# render mail template and send it using local sendmail binary
+def sendmail(to_addr, template, c):
+ c['from_addr'] = "dev@spline.de"
+ c['to_addr'] = to_addr
+
+ msg = render_to_string(template + "_mail.txt", c)
+
+ # open sendmail process for writing
+ p = os.popen("/usr/sbin/sendmail -t", 'w')
+ p.write(msg)
+
+ # close will return exit status
+ # TODO: log error to some file
+ if p.close():
+ return False
+
+ return True
+
+
+# cleanup database connection after every request
+def closedb(req):
+ req.cursor.close()
+ req.dbc.close()
+
+
+# start a new session and context and register the session dictionary in our
+# global template context
+def session_start(req, anonymous):
+ req.dbc = MySQLdb.connect(host="localhost", user="apache", passwd="password", db="trac")
+ req.cursor = req.dbc.cursor()
+ req.register_cleanup(closedb, req)
+
+ s = Session.Session(req)
+
+ if not 'login' in s:
+ s['login'] = None
+
+ s.save()
+
+ req.c = Context()
+ req.c['session'] = s
+
+ # None means everyone can acccess this URL
+ # True/False means only anonymous/authenticated users can access this URL
+ if anonymous != None:
+ if (anonymous and s['login']) or (not anonymous and not s['login']):
+ redirect(req, "index")
+
+ return (req.c, s, req.cursor)
+
+
+# generate a htpasswd compatible sha1 digest in base64 encoding
+# see: http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
+def generate_sha_base64(password):
+ return "{SHA}" + base64.encodestring(sha.new(password).digest()).rstrip('\n')
+
+
+# generate a new random password, save it to the database and send it to the user
+# WARNING: this function will do an implicit commit/rollback to the database!
+def set_random_password(req, user_id, length):
+ req.c['new_password'] = ''.join([choice(string.letters) for i in range(length)])
+
+ pw_hash = generate_sha_base64(req.c['new_password'])
+ req.cursor.execute("UPDATE user SET password = %s WHERE id = %s", (pw_hash, user_id))
+
+ req.cursor.execute("SELECT email FROM user WHERE id = %s", (user_id,))
+ result = req.cursor.fetchone()
+ email = result[0]
+
+ req.cursor.execute("SELECT login FROM user WHERE id = %s AND password NOT NULL", (user_id,))
+ result = req.cursor.fetchone()
+
+ if not result:
+ template = 'registration'
+ else:
+ req.c['login'] = result[0]
+ template = 'password'
+
+ if not sendmail(email, template, req.c):
+ req.dbc.rollback()
+ return "failed to send temporary password. sorry."
+
+ # otherwise commit to database and confirm
+ req.dbc.commit()
+ return None
+
+
+def validate_and_register(req, login, email):
+ # check for invalid entries
+ if not email.endswith('.fu-berlin.de'):
+ return "you did not give a &nbsp;*.fu-berlin.de address"
+
+ req.cursor.execute("SELECT login FROM user WHERE login = %s", (login, ))
+ if req.cursor.fetchone():
+ return "username already taken, please choose another one"
+
+ req.cursor.execute("SELECT login FROM user WHERE email = %s", (email, ))
+ if req.cursor.fetchone():
+ return 'you already have an account! <a href="password">forgot your password?</a>'
+
+ # entries are valid - generate activation code and prepare insert statements
+ hash = ''.join([choice(string.letters) for i in range(10)])
+ req.cursor.execute("INSERT INTO user (login, email, date_added) VALUES (%s, %s, NOW())", (login, email))
+ req.cursor.execute("INSERT INTO activation (hash, user_id) VALUES (%s, LAST_INSERT_ID())", (hash, ))
+
+ # send confirmation email to applicant
+ req.c['activation_link'] = "https://dev.spline.de/account/activate?hash=" + hash
+
+ # in case of an error, rollback
+ if not sendmail(email, 'activation', req.c):
+ req.dbc.rollback()
+ return "failed to send confirmation link."
+
+ # otherwise commit to database
+ req.dbc.commit()
+ return None
+
+
+###############################
+# URL handlers start here #
+###############################
+
+# req = request
+def index(req):
+ (c, s, cursor) = session_start(req, None)
+ return render_to_string("index.html", c)
+
+
+def activate(req, **formdata):
+ (c, s, cursor) = session_start(req, True)
+
+ # check whether a (correct) hashcode is given in the url
+ if "hash" in formdata:
+ cursor.execute("SELECT user_id FROM activation WHERE hash = %s", (formdata['hash'],))
+ result = cursor.fetchone()
+
+ if not result:
+ c['error_msg'] = "invalid activation code"
+ else:
+ user_id = result[0]
+ cursor.execute("DELETE FROM activation WHERE user_id = %s", (user_id,))
+ cursor.execute("UPDATE user SET activated = 1 WHERE id = %s", (user_id,))
+
+ # send email containing a temporary password
+ c['error_msg'] = set_random_password(req, user_id, 8)
+
+ if not c['error_msg']:
+ c['info_msg'] = "your account has been activated. you will receive an email with a temporary password."
+
+ # no hash value given
+ else:
+ redirect(req, "index")
+
+ return render_to_string("index.html", c)
+
+
+def login(req, **formdata):
+ (c, s, cursor) = session_start(req, True)
+
+ if req.method == "POST":
+ pw_hash = generate_sha_base64(formdata['password'])
+ cursor.execute("SELECT * FROM user WHERE login = %s AND password = %s", (formdata['login'], pw_hash))
+
+ if not cursor.fetchone():
+ c['error_msg'] = "Login failed. Sorry."
+ return render_to_string("index.html", c)
+ else:
+ s['login'] = formdata['login']
+ s.save()
+
+ redirect(req, 'index')
+
+
+def logout(req):
+ (c, s, cursor) = session_start(req, False)
+ s['login'] = None
+ s.save()
+ redirect(req, 'index')
+
+
+def register(req, **formdata):
+ (c, s, cursor) = session_start(req, True)
+
+ if req.method == "POST":
+ c['error_msg'] = validate_and_register(req, formdata['login'], formdata['email'])
+ if not c['error_msg']:
+ c['info_msg'] = "we have sent an email to " + formdata['email'] + " with your confirmation link"
+ return render_to_string("index.html", c)
+
+ return render_to_string("register.html", c)
+
+
+def password(req, **formdata):
+ (c, s, cursor) = session_start(req, True)
+
+ if req.method == 'POST':
+ cursor.execute("SELECT id FROM user WHERE email = %s", (formdata['email'],))
+ result = cursor.fetchone()
+
+ if not result:
+ c['error_msg'] = "unknown email address"
+ else:
+ c['error_msg'] = set_random_password(req, result[0], 8)
+
+ if not c['error_msg']:
+ c['info_msg'] = "a new temporary password has been sent to your email address"
+ return render_to_string("index.html", c)
+
+ return render_to_string("password.html", c)
+
+
+def profile(req, **formdata):
+ (c, s, cursor) = session_start(req, False)
+
+ if req.method == 'POST':
+ old_pw_hash = generate_sha_base64(formdata['old_pw'])
+ cursor.execute("SELECT * FROM user WHERE password = %s AND login = %s", (old_pw_hash,s['login']))
+
+ new_pw_bad = cracklib.FascistCheck(formdata['new_pw1'])
+
+ if not cursor.fetchone():
+ c['error_msg'] = "old pasword did not match"
+
+ elif formdata['new_pw1'] != formdata['new_pw2']:
+ c['error_msg'] = "new passwords did not match"
+
+ elif new_pw_bad:
+ c['error_msg'] = "cannot accept new password: " + new_pw_bad
+
+ else:
+ new_pw_hash = generate_sha_base64(formdata['new_pw1'])
+ cursor.execute("UPDATE user SET password = %s WHERE login = %s", (new_pw_hash, s['login']))
+ req.dbc.commit()
+
+ c['info_msg'] = "new password has been set"
+ return render_to_string("index.html", c)
+
+ cursor.execute("SELECT email FROM user WHERE login = %s", (s['login'],))
+ result = cursor.fetchone()
+ c['email'] = result[0]
+
+ return render_to_string("profile.html", c)
+
+
+def projects(req, **formdata):
+ (c, s, cursor) = session_start(req, False)
+
+ if "action" in formdata and "proj_name" in formdata:
+ if formdata['action'] == "leave":
+ cursor.execute("delete from member where user_id = (select id from user where login = %s) "
+ + "and project_id = (select id from project where project_name = %s)", (s['login'], formdata['proj_name']))
+ req.dbc.commit()
+ c['info_msg'] = "you left project " + formdata['proj_name']
+
+ elif formdata['action'] == "delete":
+ # check whether the person is member of the project he or she wants to delete
+ cursor.execute("select * from member where user_id = (select id from user where login = %s) "
+ + "and project_id = (select id from project where project_name = %s)", (s['login'], formdata['proj_name']))
+ if cursor.fetchone() != None:
+ cursor.execute("update project set deleted = 1 where project_name = %s", (formdata['proj_name'],))
+ req.dbc.commit()
+ c['info_msg'] = "you deleted project " + formdata['proj_name']
+ c['proj_name'] = formdata['proj_name']
+ sendmail("dev@spline.de", "deleted_project", c)
+
+ cursor.execute("select project_name from project p join member m on m.project_id = p.id join user u on u.id = m.user_id where p.deleted <> 1 and u.login = %s", (s['login'],))
+ c['projects'] = cursor.fetchall()
+
+ return render_to_string("projects.html", c)
+
+
+def imprint(req):
+ (c, s, cursor) = session_start(req, None)
+ return render_to_string("imprint.html", c)
+
+
+def new_project(req, **formdata):
+ (c, s, cursor) = session_start(req, False)
+
+ if req.method == "POST":
+ c['name'] = formdata['project_name']
+ c['desc'] = formdata['project_desc']
+ c['priv'] = formdata['priv']
+
+ # send message to dev.spline.de
+ sendmail("dev@spline.de", "new_project", c)
+
+ # confirm to user
+ c['info_msg'] = "your application has been sent to the dev.spline.de team. you'll receive a message shortly"
+ return render_to_string("index.html", c)
+
+ return render_to_string("new_project.html", c)
+
+
+def members(req, **formdata):
+ (c, s, cursor) = session_start(req, False)
+
+ if not "proj_name" in formdata:
+ redirect(req,"index")
+
+ proj = formdata['proj_name']
+
+ cursor.execute("select id from project where project_name = %s", (proj,))
+ result = cursor.fetchone()
+
+ if not result:
+ c['error_msg'] = "project '%s' does not exist" % proj
+ return render_to_string("index.html", c)
+
+ project_id = result[0]
+
+ # if he/she wants to add/delete members, the logged in user must be a member of the project, too
+ cursor.execute("select * from member where user_id = (select id from user where login = %s) "
+ + "and project_id = %s", (s['login'], project_id))
+
+ if cursor.fetchone() == None:
+ c['error_msg'] = "you are not a member of project '%s'" % proj
+
+ elif "login" in formdata and "action" in formdata:
+ who = formdata['login']
+ what = formdata['action']
+
+ cursor.execute("select id from user where login = %s", (who, ))
+ result = cursor.fetchone()
+
+ if result:
+ user_id = result[0]
+
+ if what == "delete":
+ cursor.execute("delete from member where user_id = %s and project_id = %s", (user_id, project_id))
+ req.dbc.commit()
+ c['info_msg'] = "you deleted " + who + " from project " + proj
+
+ elif what == "add":
+ cursor.execute("insert into member (user_id, project_id) values (%s, %s)", (user_id, project_id))
+ req.dbc.commit()
+ c['info_msg'] = "you added " + who + " to project " + proj
+
+ else:
+ c['error_msg'] = "invalid user name"
+
+ cursor.execute("select login from user u join member m on u.id = m.user_id "
+ + "where m.project_id = (select id from project where project_name = %s)", (proj,))
+ c['members'] = cursor.fetchall()
+ c['proj'] = proj
+
+ return render_to_string("members.html", c)
diff --git a/settings.py b/settings.py
new file mode 100644
index 0000000..b761747
--- /dev/null
+++ b/settings.py
@@ -0,0 +1,3 @@
+TEMPLATE_DIRS = (
+ "/var/www/localhost/htdocs/account/templates",
+)
diff --git a/templates/.index.html.swp b/templates/.index.html.swp
new file mode 100644
index 0000000..9ff5d5f
--- /dev/null
+++ b/templates/.index.html.swp
Binary files differ
diff --git a/templates/activation_mail.txt b/templates/activation_mail.txt
new file mode 100644
index 0000000..c11ffad
--- /dev/null
+++ b/templates/activation_mail.txt
@@ -0,0 +1,13 @@
+From: {{ from_addr }}
+Subject: dev.spline.de activation link
+To: {{ to_addr }}
+
+You or someone else registered a dev.spline.de account for {{ to_addr }}.
+
+To confirm your registration, please visit the following website:
+{{ activation_link }}
+
+If you did not register, you don't need to do anything and your request will be deleted within 24 hours.
+
+Yours,
+ the dev.spline.de team
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 0000000..0828ba4
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>dev.spline.de - {% block title %}Welcome{% endblock %}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link href="/css/layout.css" rel="stylesheet" type="text/css" />
+ <!--[if lte IE 7]>
+ <link href="/css/patches/patch_layout.css" rel="stylesheet" type="text/css" />
+ <![endif]-->
+ <script src="/js/form.js" type="text/javascript"></script>
+</head>
+<body>
+ <div id="page_margins">
+ <div id="page">
+ <div id="header">
+ <div class="subcolumns">
+ <div class="c50l">
+ <a href="/"><img id="logo" src="/img/logo.png" alt="logo" /></a>
+ </div>
+ <div class="c50r" style="text-align: right;">
+ {% if session.login %}
+ you are logged in as <em>{{ session.login }}</em>
+ {% endif %}
+ </div>
+ </div>
+ </div>
+ {% if info_msg %}
+ <div id="info">
+ {{ info_msg }}
+ </div>
+ {% endif %}
+ {% if error_msg %}
+ <div id="error">
+ {{ error_msg }}
+ </div>
+ {% endif %}
+ <div id="main">
+ <div id="col1">
+ <div id="col1_content" class="clearfix">
+ <div class="nav navbox">
+ <a href="/trac/">Project Listing</a>
+ </div>
+ {% if session.login %}
+ <div id="nav" class="nav navbox">
+ <a href="new_project">New Project</a>
+ <a href="projects">My Projects</a>
+ <a href="profile">My Profile</a>
+ <a href="logout">Logout</a>
+ </div>
+ {% else %}
+ <div id="login" class="navbox">
+ <p>Sign in with your dev.spline.de account</p>
+ <form action="login" method="post">
+ <input id="login_input" type="text" name="login" value="login" onfocus="clearInput('login_input')" />
+ <input id="password_input" type="password" name="password" value="password" onfocus="clearInput('password_input')" />
+ <input type="submit" value="Login"/>
+ </form>
+ <p><a href="password">I forgot my password</a></p>
+ </div>
+ <div id="register" class="navbox">
+ <p>Don't have a dev.spline.de account?<br/><br/>
+ <a href="register">Create an account now</a></p>
+ </div>
+ {% endif %}
+ </div>
+ </div>
+ <div id="col3">
+ <div id="col3_content" class="clearfix">
+ {% block content %}{% endblock %}
+ </div>
+ <!-- IE Column Clearing -->
+ <div id="ie_clearing"> &#160; </div>
+ </div>
+ </div>
+ <!-- begin: #footer -->
+ <div id="footer">
+ <div class="subcolumns">
+ <div class="c50l">
+ dev.spline.de is operated by <a href="http://www.spline.de/">spline</a>
+ </div>
+ <div class="c50r" style="text-align: right">
+ <a href="/">home</a> |
+ <a href="/account/imprint">imprint</a>
+ </div>
+ </div>
+ </div>
+ {% if debug_msg %}
+ <div id="debug">
+ {{ debug_msg }}
+ </div>
+ {% endif %}
+ </div>
+ </div>
+</body>
+</html>
diff --git a/templates/deleted_project_mail.txt b/templates/deleted_project_mail.txt
new file mode 100644
index 0000000..712c72e
--- /dev/null
+++ b/templates/deleted_project_mail.txt
@@ -0,0 +1,11 @@
+From: {{ from_addr }}
+Subject: {{ session.login }} wants to delete project {{ project_name }}
+To: {{ to_addr }}
+
+Hi dev.spline.de team,
+
+{{ session.login }} requested the deletion of project {{ project_name }}.
+Please take care of it ASAP.
+
+Yours,
+ dev.spline.de
diff --git a/templates/imprint.html b/templates/imprint.html
new file mode 100644
index 0000000..3200652
--- /dev/null
+++ b/templates/imprint.html
@@ -0,0 +1,29 @@
+{% extends "base.html" %}
+{% block title %}Imprint{% endblock %}
+{% block content %}
+<h1>Imprint</h1>
+
+<strong>Impressum gem&auml;&szlig; &sect; 6 TDG und &sect; 10 Mediendienstestaatsvertrag</strong>
+<table>
+ <tr>
+ <th>Institution:</th>
+ <td>Freie Universit&auml;t Berlin - vertreten durch den Pr&auml;sidenten Univ.-Prof. Dr. Dieter Lenzen</td>
+ </tr>
+ <tr>
+ <th>Anschrift:</th>
+ <td><address>Fachbereich Mathematik und Informatik, Arnimallee 14, 14195 Berlin</address></td>
+ </tr>
+ <tr>
+ <th>Kontakt:</th>
+ <td>fbv@mi.fu-berlin.de, Tel. +49-30-838-754 51</td>
+ </tr>
+ <tr>
+ <th>Rechtsform:</th>
+ <td>Die Freie Universit&auml;t Berlin ist eine K&ouml;rperschaft des &ouml;ffentlichen Rechts gem. &sect;&sect; 1 und 2 Berliner Hochschulgesetz (BerlHG)</td>
+ </tr>
+ <tr>
+ <th>UST-Id:</th>
+ <td>DE 811304768</td>
+ </tr>
+</table>
+{% endblock %}
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..f5c2107
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+{% block title %}Welcome{% endblock %}
+{% block content %}
+<h1>Welcome to dev.spline.de</h1>
+<p style="text-align: justify;">
+dev.spline.de is a collaborative workspace for the staff and students at the
+<a href="http://www.fu-berlin.de">Freie Universität Berlin</a>
+<a href="http://mi.fu-berlin.de">Department of Mathematics and Computer Science</a>.
+It is based on
+<a href="http://trac.edgewall.org">Trac</a>,
+an enhanced wiki and issue tracking system for software development projects,
+and maintained by the members of
+<a href="http://www.spline.de">spline</a>.
+The system has tools to help your team collaborate, like wiki pages and
+mailing lists as well as tools to create and control access to source code management repositories.
+</p>
+{% endblock %}
diff --git a/templates/members.html b/templates/members.html
new file mode 100644
index 0000000..2da38c0
--- /dev/null
+++ b/templates/members.html
@@ -0,0 +1,37 @@
+{% extends "base.html" %}
+{% block title %}Members of project {{ proj }}{% endblock %}
+{% block content %}
+<h1>Members of project {{ proj }}</h1>
+<p style="font-size: small; padding-bottom: 5px;">
+Add or delete members to/from project {{ proj }}
+</p>
+<div class="subcolumns">
+ <div class="c66l">
+ <table>
+ <tr>
+ <th style="width: 100%">member name</th>
+ <th>delete?</th>
+ </tr>
+ {% for member in members %}
+ <tr>
+ <td>{{ member.0 }}</td>
+ <td><a href="members?action=delete&proj_name={{ proj }}&login={{ member.0 }}">delete</a></td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+ <div class="c33r">
+ <form action="members" method="post">
+ <div class="infobox" style="width:150px; border-color:#132E28; margin-left:0.4cm;">
+ <p>add <input name="login" style="font-style:italic; color:grey;"
+ type="text" value="name of user to add" size="12" maxlength="64" id="mem" onclick="clearInput('mem')"/><br/>
+ to project <em>{{ proj }}</em><br/>
+ <input type="hidden" name="action" value="add" />
+ <input type="hidden" name="proj_name" value="{{ proj }}" />
+ <input type="submit" value="submit"/>
+ </p>
+ </div>
+ </form>
+ </div>
+</div>
+{% endblock %}
diff --git a/templates/new_project.html b/templates/new_project.html
new file mode 100644
index 0000000..f89ad0a
--- /dev/null
+++ b/templates/new_project.html
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% block title %}New project{% endblock %}
+{% block content %}
+<h1>Apply for a new project</h1>
+<form action="new_project" method="post" class="cmxform">
+ <p style="font-size: small; padding-bottom: 5px;">
+ Please complete the form below to apply for a new project.
+ </p>
+ <fieldset>
+ <ol>
+ <li>
+ <label for="name">project name</label>
+ <input id="name" type="text" name="project_name" value="your project's name" onfocus="clearInput('name')"/>
+ </li>
+ <li>
+ <label for="desc">project description</label>
+ <textarea id="desc" style="width: 70%;" type="text" name="project_desc" onfocus="clearInput('desc')" rows="10" maxlength="500">describe your project here</textarea>
+ </li>
+ <li>
+ <fieldset>
+ <legend>i want my project to be <em>*</em></legend>
+ <label><input type="radio" name="priv" value="open" checked="checked" /> open</label>
+ <label><input type="radio" name="priv" value="private" /> private</label>
+ </fieldset>
+ </li>
+ </ol>
+ </fieldset>
+ <p><input type="submit" value="Submit" /></p>
+</form>
+<hr style="margin: 20px 0 10px; width: 40%; color: #C9DCA6;" />
+<p style="width: 85%; font-size:11px; color:dark-gray; text-align:justify;">
+<em>*</em> it is recommended that your project is <em>open</em>. this means read-access for everyone (<em>open source!</em>).<br/>
+a <em>private</em> project will grant read- and write-access only to its members.
+</p>
+{% endblock %}
diff --git a/templates/new_project_mail.txt b/templates/new_project_mail.txt
new file mode 100644
index 0000000..e69a212
--- /dev/null
+++ b/templates/new_project_mail.txt
@@ -0,0 +1,15 @@
+From: {{ from_addr }}
+Subject: new project application from {{ session.login }} !
+To: {{ to_addr }}
+
+hello dev.spline.de,
+
+{{ session.login }} has applied for a new project called {{ name }}.
+
+the description is:
+{{ desc }}
+
+he or she wishes the project to be {{ priv }}.
+
+please attend to the matter soon,
+ dev.spline.de
diff --git a/templates/password.html b/templates/password.html
new file mode 100644
index 0000000..ec5b091
--- /dev/null
+++ b/templates/password.html
@@ -0,0 +1,19 @@
+{% extends "base.html" %}
+{% block title %}Request new password{% endblock %}
+{% block content %}
+<h1>Request new password</h1>
+<form action="password" method="post" class="cmxform">
+ <p style="font-size: small; padding-bottom: 5px;">
+ Please complete the form below to get a new temporary password
+ </p>
+ <fieldset>
+ <ol>
+ <li>
+ <label for="email">E-Mail</label>
+ <input id="email_input" type="text" name="email" value="you@*.fu-berlin.de" onfocus="clearInput('email_input')"/>
+ </li>
+ </ol>
+ </fieldset>
+ <p><input type="submit" value="Submit" /></p>
+</form>
+{% endblock %}
diff --git a/templates/password_mail.txt b/templates/password_mail.txt
new file mode 100644
index 0000000..7b43726
--- /dev/null
+++ b/templates/password_mail.txt
@@ -0,0 +1,12 @@
+From: {{ from_addr }}
+Subject: dev.spline.de temporary password
+To: {{ to_addr }}
+
+Dear {{ login }},
+
+You have requested a new temporary password. This is it:
+{{ new_password }}
+Please change it at your convenience.
+
+Enjoy,
+ the dev.spline.de team
diff --git a/templates/profile.html b/templates/profile.html
new file mode 100644
index 0000000..59ecc6c
--- /dev/null
+++ b/templates/profile.html
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% block title %}Profile{% endblock %}
+{% block content %}
+<h1>Your profile</h1>
+<form action="profile" method="post" class="cmxform">
+ <p style="font-size: small; padding-bottom: 5px;">
+ Please complete the form below if you want to change your password.
+ </p>
+ <fieldset>
+ <ol>
+ <li>
+ <label for="login">login</label>
+ <input class="nomodify" type="text" name="login" readonly="readonly" value="{{ session.login }}"/>
+ </li>
+ <li>
+ <label for="email">email</label>
+ <input class="nomodify" type="text" name="email" readonly="readonly" value="{{ email }}"/>
+ </li>
+ <li>
+ <label for="old_pw">old password</label>
+ <input type="password" name="old_pw" />
+ </li>
+ <li>
+ <label for="new_pw1">new password</label>
+ <input type="password" name="new_pw1" />
+ </li>
+ <li>
+ <label for="new_pw2">retype new password</label>
+ <input type="password" name="new_pw2" />
+ </li>
+ </ol>
+ </fieldset>
+ <p><input type="submit" value="Submit" /></p>
+</form>
+{% endblock %}
diff --git a/templates/projects.html b/templates/projects.html
new file mode 100644
index 0000000..d3dd1c3
--- /dev/null
+++ b/templates/projects.html
@@ -0,0 +1,53 @@
+{% extends "base.html" %}
+{% block title %}Your projects{% endblock %}
+{% block content %}
+<h1>Your projects</h1>
+<p style="font-size: small; padding-bottom: 5px;">
+The projects you are currently member of:
+</p>
+<div class="subcolumns">
+ <div class="c66l">
+ <table>
+ <tr>
+ <th style="width: 100%">project name</th>
+ <th colspan="3">options</th>
+ </tr>
+ {% for proj in projects %}
+ <tr>
+ <td>{{ proj.0 }}</td>
+ <td onmouseover="showElement('box1')" onmouseout="hideElement('box1')"><a href="projects?action=leave&proj_name={{ proj.0 }}">leave</a></td>
+ <td onmouseover="showElement('box2')" onmouseout="hideElement('box2')"><a href="members?proj_name={{ proj.0 }}">members</a></td>
+ <td onmouseover="showElement('box3')" onmouseout="hideElement('box3')">
+ <a href="javascript:confirmDelete('{{ proj.0 }}', 'projects?action=delete&proj_name={{ proj.0 }}')">delete</a></td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+ <div class="c33r">
+ <div style="display:none;" id="box1" class="infobox">
+ <h1>leave project</h1>
+ <p>
+ if you leave a project, the project will still exist with all its
+ other members, but you will not be part of it any more.
+ </p>
+ </div>
+ <div style="display:none;" id="box2" class="infobox">
+ <h1>manage members</h1>
+ <p>
+ click on this link and you will see a form where you can add members to or
+ delete members from a project. you should be sure of what you're doing.
+ </p>
+ </div>
+ <div style="display:none;" id="box3" class="infobox">
+ <h1>delete project</h1>
+ <p>
+ if you delete a project, it will no longer appear in anyone's project list and will
+ soon be deleted by the dev.spline.de team.
+ you will however be provided with a backup of the project.
+ all the project's members will receive a link to a *.tar.bz2 file to download the complete
+ compressed project. after a week the link and the project will be deleted for good.
+ </p>
+ </div>
+ </div>
+</div>
+{% endblock %}
diff --git a/templates/register.html b/templates/register.html
new file mode 100644
index 0000000..1b579f3
--- /dev/null
+++ b/templates/register.html
@@ -0,0 +1,40 @@
+{% extends "base.html" %}
+{% block title %}Create new account{% endblock %}
+{% block content %}
+<h1>Create new account</h1>
+<div class="subcolumns">
+
+ <div class="c66l">
+ <form action="register" method="post" class="cmxform">
+ <p style="font-size: small; padding-bottom: 5px;">
+ Please complete the form below to register a new account
+ </p>
+ <fieldset>
+ <ol>
+ <li>
+ <label for="login">Username</label>
+ <input id="login_input" type="text" name="login" onfocus="clearInput('login_input')"/>
+ </li>
+ <li>
+ <label for="email">E-Mail</label>
+ <input id="email_input" type="text" name="email" value="you@*.fu-berlin.de" onfocus="clearInput('email_input')"/>
+ </li>
+ </ol>
+ </fieldset>
+ <p><input type="submit" value="Register" /></p>
+ </form>
+ </div>
+
+ <div class="c33r">
+ <div class="infobox">
+ <h1>I do not have a &nbsp;*.fu-berlin.de email address!</h1>
+ <p>
+ In this case write an email to <a href="mailto:dev@spline.de">dev@spline.de</a> and
+ give a good reason why you need a dev.spline.de account.
+ <br/>
+ Policy has it, that usually we only accept members of the FU-Berlin.
+ </p>
+ </div>
+ </div>
+</div>
+{% endblock %}
diff --git a/templates/registration_mail.txt b/templates/registration_mail.txt
new file mode 100644
index 0000000..7047704
--- /dev/null
+++ b/templates/registration_mail.txt
@@ -0,0 +1,11 @@
+From: {{ from_addr }}
+Subject: dev.spline.de temporary password
+To: {{ to_addr }}
+
+Welcome to dev.spline.de !
+
+You registered successfully. Your temporary password is {{ new_password }}
+Please change it at your convenience.
+
+Enjoy,
+ the dev.spline.de team