From 90cd412923fedeac8f5a4abb9b17ba787990cc53 Mon Sep 17 00:00:00 2001 From: Hostmaster of the Day Date: Fri, 1 Apr 2011 02:30:27 +0200 Subject: commited uncommited changes --- gen_password.py | 6 - index.py | 587 +++++++++++++++++++------------------ templates/base.html | 2 +- templates/delete_reminder_mail.txt | 19 ++ templates/deleted_project_mail.txt | 4 +- templates/new_project.html | 12 +- templates/new_project_mail.txt | 4 +- templates/register.html | 4 +- 8 files changed, 332 insertions(+), 306 deletions(-) delete mode 100644 gen_password.py create mode 100644 templates/delete_reminder_mail.txt diff --git a/gen_password.py b/gen_password.py deleted file mode 100644 index 19b7781..0000000 --- a/gen_password.py +++ /dev/null @@ -1,6 +0,0 @@ -import base64, cracklib, sha, string, os - -# 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): - print "{SHA}" + base64.encodestring(sha.new(password).digest()).rstrip('\n') diff --git a/index.py b/index.py index 781cc43..8922e3a 100644 --- a/index.py +++ b/index.py @@ -23,110 +23,111 @@ import base64, cracklib, sha, string, os, re # 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 + c['from_addr'] = "dev@spline.de" + c['to_addr'] = to_addr - msg = render_to_string(template + "_mail.txt", c) + msg = render_to_string(template + "_mail.txt", c) - # open sendmail process for writing - p = os.popen("/usr/sbin/sendmail -t", 'w') - p.write(msg) + # open sendmail process for writing + p = os.popen("/usr/sbin/sendmail -t", 'w') + p.write(msg.encode('utf8')) - # close will return exit status - # TODO: log error to some file - if p.close(): - return False + # close will return exit status + # TODO: log error to some file + if p.close(): + return False - return True + return True # cleanup database connection after every request def closedb(req): - req.cursor.close() - req.dbc.close() + 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): - try: - req.dbc = MySQLdb.connect(host="localhost", user="apache", passwd="password", db="trac") - except: - redirect(req, "db_error") + try: + req.dbc = MySQLdb.connect(host="localhost", user="apache", passwd="password", db="trac") + except: + redirect(req, "db_error") - req.cursor = req.dbc.cursor() - req.register_cleanup(closedb, req) + req.cursor = req.dbc.cursor() + req.register_cleanup(closedb, req) - s = Session.Session(req) + s = Session.Session(req) - if not 'login' in s: - s['login'] = None + if not 'login' in s: + s['login'] = None - s.save() + s.save() - req.c = Context() - req.c['session'] = s + 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") + # 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) + 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') + return "{SHA}" + base64.encodestring(sha.new(password).digest()).rstrip('\n') # this function calls /var/www/localhost/scripts/bin/generate_users to create # project specific htpasswd files +# start via http://dev.spline.de/account/genusers def generate_users_file(cursor): - cursor.execute("SELECT project_name FROM project WHERE project_name != 'ALL'") - projects = cursor.fetchall() + cursor.execute("SELECT project_name FROM project WHERE project_name != 'ALL'") + projects = cursor.fetchall() - for project in projects: - cursor.execute("SELECT DISTINCT login, password FROM project_members WHERE password IS NOT NULL AND (project_name = %s OR project_name = 'ALL')", (project[0],)) - users = cursor.fetchall() - htpasswd = open("/var/www/localhost/users/" + project[0], "w") + for project in projects: + cursor.execute("SELECT DISTINCT login, password FROM project_members WHERE password IS NOT NULL AND (project_name = %s OR project_name = 'ALL')", (project[0],)) + users = cursor.fetchall() + htpasswd = open("/var/www/localhost/users/" + project[0], "w") - for user in users: - htpasswd.write("%s:%s\n" % (user[0], user[1])) + for user in users: + htpasswd.write("%s:%s\n" % (user[0], user[1])) - htpasswd.close() + htpasswd.close() # 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)]) + 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)) + 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 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 IS NOT NULL", (user_id,)) - result = req.cursor.fetchone() + req.cursor.execute("SELECT login FROM user WHERE id = %s AND password IS NOT NULL", (user_id,)) + result = req.cursor.fetchone() - if not result: - template = 'registration' - else: - req.c['login'] = result[0] - template = 'password' + 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." + 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() - generate_users_file(req.cursor) - return None + # otherwise commit to database and confirm + req.dbc.commit() + generate_users_file(req.cursor) + return None # Ditch nonsense email addresses. @@ -166,47 +167,47 @@ def invalid(emailaddress, domains = GENERIC_DOMAINS): def validate_and_register(req, login, email): - # check for invalid entries + # check for invalid entries - # empty login - if login == "": - return "please enter a username" + # empty login + if login == "": + return "please enter a username" - if not re.match("^[a-z._]{3,25}$", login): - return "your login is either too long, too short, or contains other characters than [a-z] including . and _" + if not re.match("^[a-z._]{3,25}$", login): + return "your login is either too long, too short, or contains other characters than [a-z] including . and _" - # no fu-berlin.de address - if not email.endswith('.fu-berlin.de'): - return "you did not give a  *.fu-berlin.de address" + # no fu-berlin.de address + if not email.endswith('fu-berlin.de'): + return "you did not give a  *.fu-berlin.de address" - # regex checker for valid email - if invalid(email): - return "please enter a valid email address" + # regex checker for valid email + if invalid(email): + return "please enter a valid email 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 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! forgot your password?' + req.cursor.execute("SELECT login FROM user WHERE email = %s", (email, )) + if req.cursor.fetchone(): + return 'you already have an account! forgot your password?' - # 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, )) + # 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 + # 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." + # 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 + # otherwise commit to database + req.dbc.commit() + return None ############################### @@ -215,299 +216,303 @@ def validate_and_register(req, login, email): # req = request def index(req): - (c, s, cursor) = session_start(req, None) - return render_to_string("index.html", c) + (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) + (c, s, cursor) = session_start(req, True) - # check whether a (correct) hashcode is given in the url - if "hash" in formdata and ('activated' not in s or not s['activated']): - cursor.execute("SELECT user_id FROM activation WHERE hash = %s", (formdata['hash'],)) - result = cursor.fetchone() + # check whether a (correct) hashcode is given in the url + if "hash" in formdata and ('activated' not in s or not s['activated']): + 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,)) + 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) + # send email containing a temporary password + c['error_msg'] = set_random_password(req, user_id, 8) - if not c['error_msg']: - s['activated'] = True - s.save() - c['info_msg'] = "your account has been activated. you will receive an email with a temporary password." + if not c['error_msg']: + s['activated'] = True + s.save() + c['info_msg'] = "your account has been activated. you will receive an email with a temporary password." - return render_to_string("index.html", c) + return render_to_string("index.html", c) def login(req, **formdata): - (c, s, cursor) = session_start(req, True) + (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 AND activated = 1", (formdata['login'], pw_hash)) + if req.method == "POST": + pw_hash = generate_sha_base64(formdata['password']) + cursor.execute("SELECT * FROM user WHERE login = %s AND password = %s AND activated = 1", (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() + 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') + redirect(req, 'index') def logout(req): - (c, s, cursor) = session_start(req, False) - s['login'] = None - s.save() - redirect(req, 'index') + (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) + (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) + 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) + return render_to_string("register.html", c) def password(req, **formdata): - (c, s, cursor) = session_start(req, True) + (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 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 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) + 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) + return render_to_string("password.html", c) def profile(req, **formdata): - (c, s, cursor) = session_start(req, False) + (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'])) + 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" - 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 formdata['new_pw1'] != formdata['new_pw2']: - c['error_msg'] = "new passwords did not match" + else: + try: + cracklib.FascistCheck(formdata['new_pw1']) - elif new_pw_bad: - c['error_msg'] = "cannot accept new password: " + new_pw_bad + 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() + generate_users_file(req.cursor) + c['info_msg'] = "new password has been set" - 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() - generate_users_file(req.cursor) + return render_to_string("index.html", c) + except ValueError, ex: + c['error_msg'] = "cannot accept new password: " + ex.message - 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] + 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) + 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("select count(*) from member where project_id = (select id from project where project_name = %s)") - result = cursor.fetchone() - if result[0] == 1: - c['error_msg'] = "you cannot leave this project! you're its only member! maybe you want to delete it?" - else: - 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() - generate_users_file(req.cursor) - 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) + (c, s, cursor) = session_start(req, False) + + if "action" in formdata and "proj_name" in formdata: + if formdata['action'] == "leave": + cursor.execute("select count(*) from member where project_id = (select id from project where project_name = %s)", (formdata['proj_name'],)) + result = cursor.fetchone() + if result[0] == 1: + c['error_msg'] = "you cannot leave this project! you're its only member! maybe you want to delete it?" + else: + 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() + generate_users_file(req.cursor) + 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) + (c, s, cursor) = session_start(req, None) + return render_to_string("imprint.html", c) def contact(req): - (c, s, cursor) = session_start(req, None) - return render_to_string("contact.html", c) + (c, s, cursor) = session_start(req, None) + return render_to_string("contact.html", c) def new_project(req, **formdata): - (c, s, cursor) = session_start(req, False) + (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'] + umlauts = False + if req.method == "POST": + c['name'] = formdata['project_name'] + c['desc'] = formdata['project_desc'] + c['priv'] = formdata['priv'] - cursor.execute("SELECT email FROM user WHERE login = %s", (s['login'],)) - c['email'] = cursor.fetchone()[0] + cursor.execute("SELECT email FROM user WHERE login = %s", (s['login'],)) + c['email'] = cursor.fetchone()[0] - cursor.execute("SELECT id FROM project WHERE project_name = %s", (c['name'], )) - if cursor.fetchone(): - c['error_msg'] = "project %s already exists." % c['name'] - elif len(c['name']) < 3: - c['error_msg'] = "project name must be at least 3 chars long" - elif len(c['desc']) < 0: - c['error_msg'] = "project description may not be empty" - else: - # send message to dev.spline.de - sendmail("dev@spline.de", "new_project", c) + cursor.execute("SELECT id FROM project WHERE project_name = %s", (c['name'], )) + if cursor.fetchone(): + c['error_msg'] = "project %s already exists." % c['name'] + elif len(c['name']) < 3: + c['error_msg'] = "project name must be at least 3 chars long" + elif len(c['desc']) < 0: + c['error_msg'] = "project description may not be empty" + elif c['name'] == "test": + c['error_msg'] = "NO TEST PROJECTS" + else: + # 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) + # 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) + return render_to_string("new_project.html", c) def members(req, **formdata): - (c, s, cursor) = session_start(req, False) + (c, s, cursor) = session_start(req, False) - if not "proj_name" in formdata: - redirect(req,"index") + if not "proj_name" in formdata: + redirect(req,"index") - proj = formdata['proj_name'] + proj = formdata['proj_name'] - cursor.execute("select id from project where project_name = %s", (proj,)) - result = cursor.fetchone() + 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) + if not result: + c['error_msg'] = "project '%s' does not exist" % proj + return render_to_string("index.html", c) - project_id = result[0] + 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 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 + 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'] + 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() + cursor.execute("select id from user where login = %s", (who, )) + result = cursor.fetchone() - if result: - user_id = result[0] + 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() - generate_users_file(req.cursor) - c['info_msg'] = "you deleted " + who + " from project " + proj + if what == "delete": + cursor.execute("delete from member where user_id = %s and project_id = %s", (user_id, project_id)) + req.dbc.commit() + generate_users_file(req.cursor) + c['info_msg'] = "you deleted " + who + " from project " + proj - elif what == "add": - cursor.execute("select * from member where user_id = %s and project_id = %s", (user_id, project_id)); - if cursor.fetchone() == None: - cursor.execute("insert into member (user_id, project_id) values (%s, %s)", (user_id, project_id)) - req.dbc.commit() - generate_users_file(req.cursor) - c['info_msg'] = "you added " + who + " to project " + proj - else: - c['error_msg'] = who + " is already a member of project " + proj + elif what == "add": + cursor.execute("select * from member where user_id = %s and project_id = %s", (user_id, project_id)); + if cursor.fetchone() == None: + cursor.execute("insert into member (user_id, project_id) values (%s, %s)", (user_id, project_id)) + req.dbc.commit() + generate_users_file(req.cursor) + c['info_msg'] = "you added " + who + " to project " + proj + else: + c['error_msg'] = who + " is already a member of project " + proj - else: - c['error_msg'] = "invalid user name" + 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 + 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) + return render_to_string("members.html", c) def del_profile(req): - (c, s, cursor) = session_start(req, False) + (c, s, cursor) = session_start(req, False) - cursor.execute("delete from user where login = %s", (s['login'], )) - req.dbc.commit() - generate_users_file(req.cursor) + cursor.execute("delete from user where login = %s", (s['login'], )) + req.dbc.commit() + generate_users_file(req.cursor) - s['login'] = None - s.save() + s['login'] = None + s.save() - c['info_msg'] = "your profile has been deleted successfully" + c['info_msg'] = "your profile has been deleted successfully" - return render_to_string("index.html", c) + return render_to_string("index.html", c) def list_projects(req): - (c, s, cursor) = session_start(req, None) + (c, s, cursor) = session_start(req, None) - cursor.execute("SELECT project_name FROM project WHERE private = 0 AND project_name != 'ALL' ORDER BY project_name") - result = cursor.fetchall() + cursor.execute("SELECT project_name FROM project WHERE private = 0 AND project_name != 'ALL' ORDER BY project_name") + result = cursor.fetchall() - c['public_projects'] = [] + c['public_projects'] = [] - for project in result: - ini = trac.config.Configuration('/var/lib/trac/' + project[0] + '/conf/trac.ini') - c['public_projects'].append((project[0], ini.get('project', 'name'), ini.get('project','descr'))) + for project in result: + ini = trac.config.Configuration('/var/lib/trac/' + project[0] + '/conf/trac.ini') + c['public_projects'].append((project[0], ini.get('project', 'name'), ini.get('project','descr'))) - cursor.execute("SELECT project_name FROM project WHERE private = 1 AND project_name != 'ALL' ORDER BY project_name") - result = cursor.fetchall() + cursor.execute("SELECT project_name FROM project WHERE private = 1 AND project_name != 'ALL' ORDER BY project_name") + result = cursor.fetchall() - c['private_projects'] = [] + c['private_projects'] = [] - for project in result: - ini = trac.config.Configuration('/var/lib/trac/' + project[0] + '/conf/trac.ini') - c['private_projects'].append((project[0], ini.get('project', 'name'), ini.get('project','descr'))) + for project in result: + ini = trac.config.Configuration('/var/lib/trac/' + project[0] + '/conf/trac.ini') + c['private_projects'].append((project[0], ini.get('project', 'name'), ini.get('project','descr'))) - return render_to_string("list_projects.html", c) + return render_to_string("list_projects.html", c) def genusers(req): - (c, s, cursor) = session_start(req, None) - generate_users_file(cursor) - return "OK" + (c, s, cursor) = session_start(req, None) + generate_users_file(cursor) + return "OK" # this is returned whenever a db error occurs def db_error(req): diff --git a/templates/base.html b/templates/base.html index 6e04fea..200a316 100644 --- a/templates/base.html +++ b/templates/base.html @@ -58,7 +58,7 @@

I forgot my password

{% endif %} diff --git a/templates/delete_reminder_mail.txt b/templates/delete_reminder_mail.txt new file mode 100644 index 0000000..44e76b6 --- /dev/null +++ b/templates/delete_reminder_mail.txt @@ -0,0 +1,19 @@ +From: {{ from_addr }} +Subject: dev reminder +To: {{ to_addr }} + +Hi {{ name }}, + +you are member of one or more dev.spline.de project(s): +{{ projects }} +if any of your projects is no longer needed we ask you to delete it. +you will be supplied with a full backup of your project, so no data will be +lost in case you may need it later. + +!you should not delete projects that other people might still be using! + +to delete projects, log in to https://dev.spline.de and click on 'my projects'. +next to each project name you will find a link to delete the project. + +Yours, + dev.spline.de diff --git a/templates/deleted_project_mail.txt b/templates/deleted_project_mail.txt index c75aa54..cdb9a3a 100644 --- a/templates/deleted_project_mail.txt +++ b/templates/deleted_project_mail.txt @@ -4,8 +4,8 @@ To: {{ to_addr }} Hi dev.spline.de team, -{{ session.login }} requested the deletion of project {{ proj_name }}. -Please take care of it ASAP. +{{ session.login }} requested the deletion of project {{ proj_name }} +Please take care of it soon (but at your convenience, of course!). Yours, dev.spline.de diff --git a/templates/new_project.html b/templates/new_project.html index f89ad0a..0efc2bd 100644 --- a/templates/new_project.html +++ b/templates/new_project.html @@ -12,13 +12,19 @@ +
  • How should I name my project?


    + We would be grateful if you could give your project an unambiguous name. For example, calling your + project mafi3 would definitely NOT be unambiguous, but loginname_ss2010_mafi3 would be well chosen.
    + We also do prefer lower-case letters, no white space and no dots in the project name. And there will be NO projects called test. + If you were just about to write 'test', forget it! No! There will be no test projects! +
  • - i want my project to be * + i want my project to be *
    @@ -29,7 +35,7 @@

    -* it is recommended that your project is open. this means read-access for everyone (open source!).
    -a private project will grant read- and write-access only to its members. +* It is recommended that your project is open. this means read- (but not write-) access for everyone (open source!). + A private project will grant read- and write-access only to its members.

    {% endblock %} diff --git a/templates/new_project_mail.txt b/templates/new_project_mail.txt index 3a056c4..e9ea91d 100644 --- a/templates/new_project_mail.txt +++ b/templates/new_project_mail.txt @@ -2,10 +2,12 @@ From: {{ from_addr }} Reply-To: {{ email }} Subject: new project application from {{ session.login }} ! To: {{ to_addr }} +Content-Type: text/plain; charset="utf8" +Content-Transfer-Encoding: 8bit hello dev.spline.de, -{{ session.login }} has applied for a new project called {{ name }}. +{{ session.login }} has applied for a new project called {{ name }} the description is: {{ desc }} diff --git a/templates/register.html b/templates/register.html index 1b579f3..f197ab0 100644 --- a/templates/register.html +++ b/templates/register.html @@ -17,7 +17,7 @@
  • - +
  • @@ -27,7 +27,7 @@
    -

    I do not have a  *.fu-berlin.de email address!

    +

    I do not have a  *fu-berlin.de email address!

    In this case write an email to dev@spline.de and give a good reason why you need a dev.spline.de account. -- cgit v1.2.3