summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c83b872)
raw | patch | inline | side by side (parent: c83b872)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Tue, 9 Oct 2001 07:25:59 +0000 (07:25 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Tue, 9 Oct 2001 07:25:59 +0000 (07:25 +0000) |
implementation details. Have updated some of the documentation too.
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@278 57a73879-2fb5-44c3-a270-3262357dd7e2
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@278 57a73879-2fb5-44c3-a270-3262357dd7e2
17 files changed:
CHANGES.txt | patch | blob | history | |
doc/announcement.txt | patch | blob | history | |
doc/index.html | patch | blob | history | |
roundup-admin | patch | blob | history | |
roundup/backends/back_anydbm.py | patch | blob | history | |
roundup/backends/back_bsddb.py | patch | blob | history | |
roundup/backends/back_bsddb3.py | patch | blob | history | |
roundup/cgi_client.py | patch | blob | history | |
roundup/htmltemplate.py | patch | blob | history | |
roundup/hyperdb.py | patch | blob | history | |
roundup/init.py | patch | blob | history | |
roundup/mailgw.py | patch | blob | history | |
roundup/password.py | [new file with mode: 0644] | patch | blob |
roundup/templates/classic/dbinit.py | patch | blob | history | |
roundup/templates/extended/dbinit.py | patch | blob | history | |
test/test_db.py | patch | blob | history | |
test/test_schema.py | patch | blob | history |
diff --git a/CHANGES.txt b/CHANGES.txt
index 1add3f6d9909a755d2206c0e9d1f032068eff124..b20e4ae0ef926cb75f922f4bdc6cd634640befa6 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
. The schemas have had their page headings modified to cope with the new
login handling. Existing installations should copy the interfaces.py
file from the roundup lib directory to their instance home.
+ . Passwords are now encoded by default (except exising databases which
+ will only be encoded when the passwords are changed). The scheme used
+ at the moment is SHA - but the code is flexible enough to take any
+ number of encoding systems.
+ . The roundup-admin tool always operates as the "admin" user now. Database
+ protection should be achieved using file system protections (see the
+ documentation for details.)
Fixed:
. Incorrectly had a Bizar Software copyright on the cgitb.py module from
. Fixed a deviation from the spec: trying to modify the 'id' property of
an item now throws an exception.
. The plain() template function now html-escapes the content.
+ . Change message was stuffing up for multilinks with no key property.
---------------------
2001-08-30 - 0.2.8
Fixed:
diff --git a/doc/announcement.txt b/doc/announcement.txt
index 4e04ced8438eee97ee9315509781b58a63816c8f..cabdc4cb11110da52135f20566fbf17fa3052cd0 100644 (file)
--- a/doc/announcement.txt
+++ b/doc/announcement.txt
Roundup 0.3.0 - an issue tracking system
-** note for existing users of extended schema
+** existing users _must_ read the MIGRATION.txt that accompanies the
+source.
-This release includes several bug fixes and usability improvements. It
-also switches the CGI interface authentication over from HTTP Basic to cookie
-based. For a more detailed in the CHANGES file accompanying the source.
+This release includes several bug fixes and usability improvements. It
+switches the CGI interface authentication over from HTTP Basic to cookie
+based. It introduces encoded password storage. For a more detailed in
+the CHANGES file accompanying the source.
Roundup is a simple-to-use and -install issue-tracking system with
command-line, web and e-mail interfaces. It is based on the winning design
diff --git a/doc/index.html b/doc/index.html
index ea67985af30de19e6a9ec2b7126408ba17e215f3..bbf54e2cc18e96433965de8e1fc66ac0a6635ca3 100644 (file)
--- a/doc/index.html
+++ b/doc/index.html
<li><a href="#startcmd">Command Line Tool</a>
<li><a href="#startweb">E-Mail Interface</a>
<li><a href="#startweb">Web Interface</a>
- <li><a href="#users">Users</a> (Users and permissions, Adding users)
+ <li><a href="#users">Users and Access Control</a> (Users and permissions, Adding users)
<li><a href="#issues">Issues</a>
</ul>
<li><a href="#guide">User Guide</a>
<li>Administration user "admin" password.
</ol>
+You should also think about whether there is going to be controlled access
+to the instance on the machine the instance is running on. That is, who can
+actually make changes to the database using the roundup-admin tool. See
+the section on <a href="#users">Users and Access Control</a> for
+information on how to secure your instance from the start.
+
+<p>
+
Roundup is configurable using an instance_config.py file in the instance home.
It should be edited before roundup is used, and may have the following
variable declarations:
following repurcussions:
<dl>
<dt><strong>Command-line interface</strong>
-<dd>The data modification commands (create, init, retire, set) are not
-available without a login, and if one is not supplied on the command line
-(-u user:pass) then it will be prompted for.
+<dd>The data modification commands (create, init, retire, set) are
+performed as the "admin" user. It is therefore important that the database
+be protected by the filesystem if protection is required. On a Unix system,
+the easiest and most flexible method of doing so is:
+<ol>
+<li>Add a new user and group to your system (e.g. "issue_tracker")
+<li>When creating a new instance home, use the following commands
+(substituting instance_home for the directory you want to use):<br>
+<pre>
+mkdir instance_home
+chown issue_tracker:issue_tracker instance_home
+chmod g+rwxs instance_home
+chmod o-rwx instance_home
+roundup-admin -i instance_home init
+</pre>
+<li>Now, edit the /etc/group line for issue_tracker so it includes the unix
+logins of all the users who are going to administer your roundup instance.
+</ol>
+
<dt><strong>E-Mail interface</strong>
<dd>Users are identified by e-mail address - a new user entry will be
created for any e-mail address that is not recognised, so users are
automatically logged in as that user. This gives them write access.
</dl>
<p>
-There has been only a half-hearted attempt to restrict certain activities
-to the "admin" user. For example, the "extended" schema web interface enables
-some fnuctionality for the "admin" user. On the fil-side, it is possible to
-obtain the admin user's password using the read-only access on the command
-line (it would also be possible to access the database files directly to
-obtain this information).
<h3>Adding users</h3>
To add users, use one of the following interfaces:
<p> </p>
<hr>
-$Id: index.html,v 1.10 2001-10-08 21:49:30 richard Exp $
+$Id: index.html,v 1.11 2001-10-09 07:25:59 richard Exp $
<p> </p>
</body></html>
diff --git a/roundup-admin b/roundup-admin
index 86bc4ae7441976703c121d78f222104a6edf2e93..85eee36243e2607bbeb6bd644c025b5d231506b0 100755 (executable)
--- a/roundup-admin
+++ b/roundup-admin
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: roundup-admin,v 1.21 2001-10-05 02:23:24 richard Exp $
+# $Id: roundup-admin,v 1.22 2001-10-09 07:25:59 richard Exp $
import sys
if int(sys.version[0]) < 2:
sys.exit(1)
import string, os, getpass, getopt, re
-from roundup import date, roundupdb, init
+from roundup import date, roundupdb, init, password
import roundup.instance
def usage(message=''):
type = properties[key]
if isinstance(type, hyperdb.String):
continue
+ elif isinstance(type, hyperdb.Password):
+ props[key] = password.Password(value)
elif isinstance(type, hyperdb.Date):
props[key] = date.Date(value)
elif isinstance(type, hyperdb.Interval):
return 0
if opt == '-i':
instance_home = arg
- if opt == '-u':
- l = arg.split(':')
- name = l[0]
- if len(l) > 1:
- password = l[1]
if opt == '-c':
comma_sep = 1
if command == 'init':
return do_init(instance_home, args)
- # open the database
- if command in ('create', 'set', 'retire', 'freshen'):
- while not name:
- name = raw_input('Login name: ')
- while not password:
- password = getpass.getpass(' password: ')
-
- # get the instance
- instance = roundup.instance.open(instance_home)
-
function = figureCommands().get(command, None)
# not a valid command
usage('Unknown command "%s"'%command)
return 1
- db = instance.open(name or 'admin')
+ # get the instance
+ instance = roundup.instance.open(instance_home)
+ db = instance.open('admin')
+
+ # do the command
try:
return function(db, args[1:])
finally:
#
# $Log: not supported by cvs2svn $
+# Revision 1.21 2001/10/05 02:23:24 richard
+# . roundup-admin create now prompts for property info if none is supplied
+# on the command-line.
+# . hyperdb Class getprops() method may now return only the mutable
+# properties.
+# . Login now uses cookies, which makes it a whole lot more flexible. We can
+# now support anonymous user access (read-only, unless there's an
+# "anonymous" user, in which case write access is permitted). Login
+# handling has been moved into cgi_client.Client.main()
+# . The "extended" schema is now the default in roundup init.
+# . The schemas have had their page headings modified to cope with the new
+# login handling. Existing installations should copy the interfaces.py
+# file from the roundup lib directory to their instance home.
+# . Incorrectly had a Bizar Software copyright on the cgitb.py module from
+# Ping - has been removed.
+# . Fixed a whole bunch of places in the CGI interface where we should have
+# been returning Not Found instead of throwing an exception.
+# . Fixed a deviation from the spec: trying to modify the 'id' property of
+# an item now throws an exception.
+#
# Revision 1.20 2001/10/04 02:12:42 richard
# Added nicer command-line item adding: passing no arguments will enter an
# interactive more which asks for each property in turn. While I was at it, I
index 9f3124081171957316d70e5a67caf0f5064bac45..a7345cd681aadf6ac0e882d65d83d8e8d0731171 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_anydbm.py,v 1.8 2001-09-29 13:27:00 richard Exp $
+#$Id: back_anydbm.py,v 1.9 2001-10-09 07:25:59 richard Exp $
import anydbm, os, marshal
-from roundup import hyperdb, date
+from roundup import hyperdb, date, password
#
# Now the database
node[key] = node[key].get_tuple()
elif isinstance(properties[key], hyperdb.Interval):
node[key] = node[key].get_tuple()
+ elif isinstance(properties[key], hyperdb.Password):
+ node[key] = str(node[key])
# now save the marshalled data
db[nodeid] = marshal.dumps(node)
res[key] = date.Date(res[key])
elif isinstance(properties[key], hyperdb.Interval):
res[key] = date.Interval(res[key])
+ elif isinstance(properties[key], hyperdb.Password):
+ p = password.Password()
+ p.unpack(res[key])
+ res[key] = p
if not cldb: db.close()
return res
#
#$Log: not supported by cvs2svn $
+#Revision 1.8 2001/09/29 13:27:00 richard
+#CGI interfaces now spit up a top-level index of all the instances they can
+#serve.
+#
#Revision 1.7 2001/08/12 06:32:36 richard
#using isinstance(blah, Foo) now instead of isFooType
#
index 4562d29900f113a21bd5b03dd7f3dab511da570d..3923fbd66279368154718def6c94ce00a3c375bc 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_bsddb.py,v 1.9 2001-08-12 06:32:36 richard Exp $
+#$Id: back_bsddb.py,v 1.10 2001-10-09 07:25:59 richard Exp $
import bsddb, os, marshal
-from roundup import hyperdb, date
+from roundup import hyperdb, date, password
#
# Now the database
node[key] = node[key].get_tuple()
elif isinstance(properties[key], hyperdb.Interval):
node[key] = node[key].get_tuple()
+ elif isinstance(properties[key], hyperdb.Password):
+ node[key] = str(node[key])
# now save the marshalled data
db[nodeid] = marshal.dumps(node)
res[key] = date.Date(res[key])
elif isinstance(properties[key], hyperdb.Interval):
res[key] = date.Interval(res[key])
+ elif isinstance(properties[key], hyperdb.Password):
+ p = password.Password()
+ p.unpack(res[key])
+ res[key] = p
if not cldb: db.close()
return res
#
#$Log: not supported by cvs2svn $
+#Revision 1.9 2001/08/12 06:32:36 richard
+#using isinstance(blah, Foo) now instead of isFooType
+#
#Revision 1.8 2001/08/07 00:24:42 richard
#stupid typo
#
index 8c402e5421041330389eb68e501759f61c45a356..1fd0eaae92af56a9d6081cab43208dca1986fb64 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_bsddb3.py,v 1.7 2001-08-12 06:32:36 richard Exp $
+#$Id: back_bsddb3.py,v 1.8 2001-10-09 07:25:59 richard Exp $
import bsddb3, os, marshal
-from roundup import hyperdb, date
+from roundup import hyperdb, date, password
#
# Now the database
node[key] = node[key].get_tuple()
elif isinstance(properties[key], hyperdb.Interval):
node[key] = node[key].get_tuple()
+ elif isinstance(properties[key], hyperdb.Password):
+ node[key] = str(node[key])
# now save the marshalled data
db[nodeid] = marshal.dumps(node)
res[key] = date.Date(res[key])
elif isinstance(properties[key], hyperdb.Interval):
res[key] = date.Interval(res[key])
+ elif isinstance(properties[key], hyperdb.Password):
+ p = password.Password()
+ p.unpack(res[key])
+ res[key] = p
if not cldb: db.close()
return res
#
#$Log: not supported by cvs2svn $
+#Revision 1.7 2001/08/12 06:32:36 richard
+#using isinstance(blah, Foo) now instead of isFooType
+#
#Revision 1.6 2001/08/07 00:24:42 richard
#stupid typo
#
diff --git a/roundup/cgi_client.py b/roundup/cgi_client.py
index a437a42b6567f6557cff2c1a141fa4aa7b7f6a84..e8e6c0ba3f230ce3b32a09764acec9cb9011683e 100644 (file)
--- a/roundup/cgi_client.py
+++ b/roundup/cgi_client.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: cgi_client.py,v 1.28 2001-10-08 00:34:31 richard Exp $
+# $Id: cgi_client.py,v 1.29 2001-10-09 07:25:59 richard Exp $
import os, cgi, pprint, StringIO, urlparse, re, traceback, mimetypes
import base64, Cookie, time
-import roundupdb, htmltemplate, date, hyperdb
+import roundupdb, htmltemplate, date, hyperdb, password
class Unauthorised(ValueError):
pass
return self.login(message='No such user "%s"'%name)
# and that the password is correct
+ pw = self.db.user.get(uid, 'password')
+ print password, pw, `pw`
if password != self.db.user.get(uid, 'password'):
+ self.make_user_anonymous()
return self.login(message='Incorrect password')
# construct the cookie
proptype = cl.properties[key]
if isinstance(proptype, hyperdb.String):
value = form[key].value.strip()
+ elif isinstance(proptype, hyperdb.Password):
+ value = password.Password(form[key].value.strip())
elif isinstance(proptype, hyperdb.Date):
value = date.Date(form[key].value.strip())
elif isinstance(proptype, hyperdb.Interval):
#
# $Log: not supported by cvs2svn $
+# Revision 1.28 2001/10/08 00:34:31 richard
+# Change message was stuffing up for multilinks with no key property.
+#
# Revision 1.27 2001/10/05 02:23:24 richard
# . roundup-admin create now prompts for property info if none is supplied
# on the command-line.
index c073a75e9ea357d6fe95227a98a775cc47dc9dcc..2bfa2b508ba72cabc3897658cda66f7d6d57ba83 100644 (file)
--- a/roundup/htmltemplate.py
+++ b/roundup/htmltemplate.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: htmltemplate.py,v 1.24 2001-09-27 06:45:58 richard Exp $
+# $Id: htmltemplate.py,v 1.25 2001-10-09 07:25:59 richard Exp $
import os, re, StringIO, urllib, cgi, errno
-import hyperdb, date
+import hyperdb, date, password
class Base:
def __init__(self, db, templates, classname, nodeid=None, form=None,
if isinstance(propclass, hyperdb.String):
if value is None: value = ''
else: value = str(value)
+ elif isinstance(propclass, hyperdb.Password):
+ if value is None: value = ''
+ else: value = '*encrypted*'
elif isinstance(propclass, hyperdb.Date):
value = str(value)
elif isinstance(propclass, hyperdb.Interval):
value = cgi.escape(value)
value = '"'.join(value.split('"'))
s = '<input name="%s" value="%s" size="%s">'%(property, value, size)
+ elif isinstance(propclass, hyperdb.Password):
+ size = size or 30
+ s = '<input type="password" name="%s" size="%s">'%(property, size)
elif isinstance(propclass, hyperdb.Link):
linkcl = self.db.classes[propclass.classname]
l = ['<select name="%s">'%property]
#
# $Log: not supported by cvs2svn $
+# Revision 1.24 2001/09/27 06:45:58 richard
+# *gak* ... xmp is Old Skool apparently. Am using pre again by have the option
+# on the plain() template function to escape the text for HTML.
+#
# Revision 1.23 2001/09/10 09:47:18 richard
# Fixed bug in the generation of links to Link/Multilink in indexes.
# (thanks Hubert Hoegl)
diff --git a/roundup/hyperdb.py b/roundup/hyperdb.py
index 32729f19d2e9d91fc662c7f6bd3ffddbcc2a7176..4a96b7bf0c8f2df998798cf419987c7a57065f3f 100644 (file)
--- a/roundup/hyperdb.py
+++ b/roundup/hyperdb.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: hyperdb.py,v 1.21 2001-10-05 02:23:24 richard Exp $
+# $Id: hyperdb.py,v 1.22 2001-10-09 07:25:59 richard Exp $
# standard python modules
import cPickle, re, string
# roundup modules
-import date
+import date, password
#
def __repr__(self):
return '<%s>'%self.__class__
+class Password:
+ """An object designating a Password property."""
+ def __repr__(self):
+ return '<%s>'%self.__class__
+
class Date:
"""An object designating a Date property."""
def __repr__(self):
if type(value) != type(''):
raise TypeError, 'new property "%s" not a string'%key
+ elif isinstance(prop, Password):
+ if not isinstance(value, password.Password):
+ raise TypeError, 'new property "%s" not a Password'%key
+
elif isinstance(prop, Date):
if not isinstance(value, date.Date):
- raise TypeError, 'new property "%s" not a Date'% key
+ raise TypeError, 'new property "%s" not a Date'%key
elif isinstance(prop, Interval):
if not isinstance(value, date.Interval):
- raise TypeError, 'new property "%s" not an Interval'% key
+ raise TypeError, 'new property "%s" not an Interval'%key
for key, prop in self.properties.items():
if propvalues.has_key(key):
if value is not None and type(value) != type(''):
raise TypeError, 'new property "%s" not a string'%key
+ elif isinstance(prop, Password):
+ if not isinstance(value, password.Password):
+ raise TypeError, 'new property "%s" not a Password'% key
+
elif isinstance(prop, Date):
if not isinstance(value, date.Date):
raise TypeError, 'new property "%s" not a Date'% key
None, or a TypeError is raised. The values of the key property on
all existing nodes must be unique or a ValueError is raised.
"""
+ # TODO: validate that the property is a String!
self.key = propname
def getkey(self):
#
# $Log: not supported by cvs2svn $
+# Revision 1.21 2001/10/05 02:23:24 richard
+# . roundup-admin create now prompts for property info if none is supplied
+# on the command-line.
+# . hyperdb Class getprops() method may now return only the mutable
+# properties.
+# . Login now uses cookies, which makes it a whole lot more flexible. We can
+# now support anonymous user access (read-only, unless there's an
+# "anonymous" user, in which case write access is permitted). Login
+# handling has been moved into cgi_client.Client.main()
+# . The "extended" schema is now the default in roundup init.
+# . The schemas have had their page headings modified to cope with the new
+# login handling. Existing installations should copy the interfaces.py
+# file from the roundup lib directory to their instance home.
+# . Incorrectly had a Bizar Software copyright on the cgitb.py module from
+# Ping - has been removed.
+# . Fixed a whole bunch of places in the CGI interface where we should have
+# been returning Not Found instead of throwing an exception.
+# . Fixed a deviation from the spec: trying to modify the 'id' property of
+# an item now throws an exception.
+#
# Revision 1.20 2001/10/04 02:12:42 richard
# Added nicer command-line item adding: passing no arguments will enter an
# interactive more which asks for each property in turn. While I was at it, I
diff --git a/roundup/init.py b/roundup/init.py
index b41561c4d1e4dd53e022d8e951230ea896751a29..f7de005fd8cbd3f714c408fe29839b26a274ed51 100644 (file)
--- a/roundup/init.py
+++ b/roundup/init.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: init.py,v 1.15 2001-08-07 00:24:42 richard Exp $
+# $Id: init.py,v 1.16 2001-10-09 07:25:59 richard Exp $
import os, shutil, sys, errno
-import roundup.instance
+import roundup.instance, password
def copytree(src, dst, symlinks=0):
"""Recursively copy a directory tree using copy2().
# now import the instance and call its init
instance = roundup.instance.open(instance_home)
- instance.init(adminpw)
+ instance.init(password.Password(adminpw))
#
# $Log: not supported by cvs2svn $
+# Revision 1.15 2001/08/07 00:24:42 richard
+# stupid typo
+#
# Revision 1.14 2001/08/07 00:15:51 richard
# Added the copyright/license notice to (nearly) all files at request of
# Bizar Software.
diff --git a/roundup/mailgw.py b/roundup/mailgw.py
index 9ce05937f54bc4c881116f90f5650421715247de..fd66143d850ac125d34e7b684357b9bfd020987e 100644 (file)
--- a/roundup/mailgw.py
+++ b/roundup/mailgw.py
an exception, the original message is bounced back to the sender with the
explanatory message given in the exception.
-$Id: mailgw.py,v 1.16 2001-10-05 02:23:24 richard Exp $
+$Id: mailgw.py,v 1.17 2001-10-09 07:25:59 richard Exp $
'''
import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
import traceback
-import hyperdb, date
+import hyperdb, date, password
class MailUsageError(ValueError):
pass
'''%(key, subject)
if isinstance(type, hyperdb.String):
props[key] = value
+ if isinstance(type, hyperdb.Password):
+ props[key] = password.Password(value)
elif isinstance(type, hyperdb.Date):
props[key] = date.Date(value)
elif isinstance(type, hyperdb.Interval):
#
# $Log: not supported by cvs2svn $
+# Revision 1.16 2001/10/05 02:23:24 richard
+# . roundup-admin create now prompts for property info if none is supplied
+# on the command-line.
+# . hyperdb Class getprops() method may now return only the mutable
+# properties.
+# . Login now uses cookies, which makes it a whole lot more flexible. We can
+# now support anonymous user access (read-only, unless there's an
+# "anonymous" user, in which case write access is permitted). Login
+# handling has been moved into cgi_client.Client.main()
+# . The "extended" schema is now the default in roundup init.
+# . The schemas have had their page headings modified to cope with the new
+# login handling. Existing installations should copy the interfaces.py
+# file from the roundup lib directory to their instance home.
+# . Incorrectly had a Bizar Software copyright on the cgitb.py module from
+# Ping - has been removed.
+# . Fixed a whole bunch of places in the CGI interface where we should have
+# been returning Not Found instead of throwing an exception.
+# . Fixed a deviation from the spec: trying to modify the 'id' property of
+# an item now throws an exception.
+#
# Revision 1.15 2001/08/30 06:01:17 richard
# Fixed missing import in mailgw :(
#
diff --git a/roundup/password.py b/roundup/password.py
--- /dev/null
+++ b/roundup/password.py
@@ -0,0 +1,111 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#
+# $Id: password.py,v 1.1 2001-10-09 07:25:59 richard Exp $
+
+import sha, re
+
+def encodePassword(plaintext, scheme):
+ '''Encrypt the plaintext password.
+ '''
+ if scheme == 'SHA':
+ s = sha.sha(plaintext).hexdigest()
+ elif scheme == 'plaintext':
+ pass
+ else:
+ raise ValueError, 'Unknown encryption scheme "%s"'%scheme
+ return s
+
+class Password:
+ '''The class encapsulates a Password property type value in the database.
+
+ The encoding of the password is one if None, 'SHA' or 'plaintext'. The
+ encodePassword function is used to actually encode the password from
+ plaintext. The None encoding is used in legacy databases where no
+ encoding scheme is identified.
+
+ The scheme is stored with the encoded data in the database:
+ {scheme}data
+
+ Example usage:
+ >>> p = Password('sekrit')
+ >>> p == 'sekrit'
+ 1
+ >>> p != 'not sekrit'
+ 1
+ >>> 'sekrit' == p
+ 1
+ >>> 'not sekrit' != p
+ 1
+ '''
+
+ default_scheme = 'SHA' # new encryptions use this scheme
+ pwre = re.compile(r'{(\w+)}(.+)')
+
+ def __init__(self, plaintext=None):
+ '''Call setPassword if plaintext is not None.'''
+ if plaintext is not None:
+ self.password = encodePassword(plaintext, self.default_scheme)
+ self.scheme = self.default_scheme
+ else:
+ self.password = None
+ self.scheme = self.default_scheme
+
+ def unpack(self, encrypted):
+ '''Set the password info from the scheme:<encryted info> string
+ (the inverse of __str__)
+ '''
+ m = self.pwre.match(encrypted)
+ if m:
+ self.scheme = m.group(1)
+ self.password = m.group(2)
+ else:
+ # currently plaintext - encrypt
+ self.password = encodePassword(plaintext, self.default_scheme)
+ self.scheme = self.default_scheme
+
+ def setPassword(self, plaintext):
+ '''Sets encrypts plaintext.'''
+ self.password = encodePassword(plaintext, self.scheme)
+
+ def __cmp__(self, plaintext):
+ '''Compare this password against the plaintext.'''
+ if self.password is None:
+ raise ValueError, 'Password not set'
+ return cmp(self.password, encodePassword(plaintext, self.scheme))
+
+ def __str__(self):
+ '''Stringify the encrypted password for database storage.'''
+ if self.password is None:
+ raise ValueError, 'Password not set'
+ return '{%s}%s'%(self.scheme, self.password)
+
+def test():
+ p = Password('sekrit')
+ assert p == 'sekrit'
+ assert p != 'not sekrit'
+ assert 'sekrit' == p
+ assert 'not sekrit' != p
+
+if __name__ == '__main__':
+ test()
+
+#
+# $Log: not supported by cvs2svn $
+#
+#
+# vim: set filetype=python ts=4 sw=4 et si
index b29fb40176c4353c121e3645a6d3abd2ca3538c5..45ee343bf99ef4c32921eabd0b82b08df9a25371 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: dbinit.py,v 1.7 2001-08-07 00:24:43 richard Exp $
+# $Id: dbinit.py,v 1.8 2001-10-09 07:25:59 richard Exp $
import os
import instance_config
-from roundup import roundupdb, cgi_client, mailgw
+from roundup import roundupdb
import select_db
from roundup.roundupdb import Class, FileClass
''' as from the roundupdb method openDB
'''
- from roundup.hyperdb import String, Date, Link, Multilink
+ from roundup.hyperdb import String, Password, Date, Link, Multilink
# open the database
db = Database(instance_config.DATABASE, name)
keyword.setkey("name")
user = Class(db, "user",
- username=String(), password=String(),
+ username=String(), password=Password(),
address=String(), realname=String(),
phone=String(), organisation=String())
user.setkey("username")
#
# $Log: not supported by cvs2svn $
+# Revision 1.7 2001/08/07 00:24:43 richard
+# stupid typo
+#
# Revision 1.6 2001/08/07 00:15:51 richard
# Added the copyright/license notice to (nearly) all files at request of
# Bizar Software.
index 93389261b80d377ecc0013ae6caee6ad39eec661..8dcbb3e6407ecce0b93d928966552ff5c568b3ba 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: dbinit.py,v 1.11 2001-08-07 00:24:43 richard Exp $
+# $Id: dbinit.py,v 1.12 2001-10-09 07:25:59 richard Exp $
import os
import instance_config
from roundup import roundupdb
import select_db
+
from roundup.roundupdb import Class, FileClass
class Database(roundupdb.Database, select_db.Database):
''' as from the roundupdb method openDB
'''
- from roundup.hyperdb import String, Date, Link, Multilink
+ from roundup.hyperdb import String, Password, Date, Link, Multilink
# open the database
db = Database(instance_config.DATABASE, name)
keywords = Class(db, "keyword",
name=String())
+ keywords.setkey("name")
user = Class(db, "user",
- username=String(), password=String(),
+ username=String(), password=Password(),
address=String(), realname=String(),
phone=String(), organisation=String())
user.setkey("username")
#
# $Log: not supported by cvs2svn $
+# Revision 1.11 2001/08/07 00:24:43 richard
+# stupid typo
+#
# Revision 1.10 2001/08/07 00:15:51 richard
# Added the copyright/license notice to (nearly) all files at request of
# Bizar Software.
diff --git a/test/test_db.py b/test/test_db.py
index d5318b65500c600299c603b2a3f224e13a78cbf2..83da8f1e3acf6dae7db9fa074cee20dce6c7e735 100644 (file)
--- a/test/test_db.py
+++ b/test/test_db.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_db.py,v 1.7 2001-08-29 06:23:59 richard Exp $
+# $Id: test_db.py,v 1.8 2001-10-09 07:25:59 richard Exp $
import unittest, os, shutil
-from roundup.hyperdb import String, Link, Multilink, Date, Interval, Class, \
- DatabaseError
+from roundup.hyperdb import String, Password, Link, Multilink, Date, \
+ Interval, Class, DatabaseError
def setupSchema(db, create):
status = Class(db, "status", name=String())
status.create(name="in-progress")
status.create(name="testing")
status.create(name="resolved")
- Class(db, "user", username=String(), password=String())
+ Class(db, "user", username=String(), password=Password())
Class(db, "issue", title=String(), status=Link("status"),
nosy=Multilink("user"))
#
# $Log: not supported by cvs2svn $
+# Revision 1.7 2001/08/29 06:23:59 richard
+# Disabled the bsddb3 module entirely in the unit testing. See CHANGES for
+# details.
+#
# Revision 1.6 2001/08/07 00:24:43 richard
# stupid typo
#
diff --git a/test/test_schema.py b/test/test_schema.py
index ce670e51b175d49ad55ef310f66dd406f1017dd3..4367e1e0096d40381b98e67fdcae2671dd48f7a0 100644 (file)
--- a/test/test_schema.py
+++ b/test/test_schema.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_schema.py,v 1.4 2001-08-07 00:24:43 richard Exp $
+# $Id: test_schema.py,v 1.5 2001-10-09 07:25:59 richard Exp $
import unittest, os, shutil
from roundup.backends import anydbm
-from roundup.hyperdb import String, Link, Multilink, Date, Interval, Class
+from roundup.hyperdb import String, Password, Link, Multilink, Date, \
+ Interval, Class
class SchemaTestCase(unittest.TestCase):
def setUp(self):
self.assert_(issue, 'no class object returned')
def testC_User(self):
- user = Class(self.db, "user", username=String(), password=String())
+ user = Class(self.db, "user", username=String(), password=Password())
self.assert_(user, 'no class object returned')
user.setkey("username")
#
# $Log: not supported by cvs2svn $
+# Revision 1.4 2001/08/07 00:24:43 richard
+# stupid typo
+#
# Revision 1.3 2001/08/07 00:15:51 richard
# Added the copyright/license notice to (nearly) all files at request of
# Bizar Software.