Exemple #1
0
def setgid(group):
    if group is None:
        return
    if not hasattr(os, 'setgid'):
        return

    # if root, setgid to the running user
    if os.getuid():
        print(_('WARNING: ignoring "-g" argument, not root'))
        return

    try:
        import grp
    except ImportError:
        raise ValueError(_("Can't change groups - no grp module"))
    try:
        try:
            gid = int(group)
        except ValueError:
            gid = grp.getgrnam(group)[2]
        else:
            grp.getgrgid(gid)
    except KeyError:
        raise ValueError(_("Group %(group)s doesn't exist") % locals())
    os.setgid(gid)
Exemple #2
0
def loadTemplateInfo(dir):
    ''' Attempt to load a Roundup template from the indicated directory.

        Return None if there's no template, otherwise a template info
        dictionary.
    '''
    ti = os.path.join(dir, 'TEMPLATE-INFO.txt')
    if not os.path.exists(ti):
        return None

    if os.path.exists(os.path.join(dir, 'config.py')):
        print _("WARNING: directory '%s'\n"
            "\tcontains old-style template - ignored"
            ) % os.path.abspath(dir)
        return None

    # load up the template's information
    f = open(ti)
    try:
        m = rfc822.Message(open(ti))
        ti = {}
        ti['name'] = m['name']
        ti['description'] = m['description']
        ti['intended-for'] = m['intended-for']
        ti['path'] = dir
    finally:
        f.close()
    return ti
Exemple #3
0
def loadTemplateInfo(path):
    ''' Attempt to load a Roundup template from the indicated directory.

        Return None if there's no template, otherwise a template info
        dictionary.
    '''
    tif = os.path.join(path, 'TEMPLATE-INFO.txt')
    if not os.path.exists(tif):
        return None

    if os.path.exists(os.path.join(path, 'config.py')):
        print _(
            "WARNING: directory '%s'\n"
            "\tcontains old-style template - ignored") % os.path.abspath(path)
        return None

    # load up the template's information
    try:
        f = open(tif)
        m = email.parser.Parser().parse(f, True)
        ti = {}
        ti['name'] = m['name']
        ti['description'] = m['description']
        ti['intended-for'] = m['intended-for']
        ti['path'] = path
    finally:
        f.close()
    return ti
Exemple #4
0
def rawToHyperdb(db, klass, itemid, propname, value, **kw):
    ''' Convert the raw (user-input) value to a hyperdb-storable value. The
        value is for the "propname" property on itemid (may be None for a
        new item) of "klass" in "db".

        The value is usually a string, but in the case of multilink inputs
        it may be either a list of strings or a string with comma-separated
        values.
    '''
    properties = klass.getprops()

    # ensure it's a valid property name
    propname = propname.strip()
    try:
        proptype = properties[propname]
    except KeyError:
        raise HyperdbValueError, _('%r is not a property of %s') % (
            propname, klass.classname)

    # if we got a string, strip it now
    if isinstance(value, type('')):
        value = value.strip()

    # convert the input value to a real property value
    value = proptype.from_raw(value,
                              db=db,
                              klass=klass,
                              propname=propname,
                              itemid=itemid,
                              **kw)

    return value
def run():
    home = DEFAULT_HOME
    template = DEFAULT_TEMPLATE
    nuke = sys.argv[-1] == 'nuke'
    # if there is no tracker in home, force nuke
    try:
        instance.open(home)
    except configuration.NoConfigError:
        nuke = 1
    # if we are to create the tracker, prompt for home
    if nuke:
        if len(sys.argv) > 2:
            backend = sys.argv[-2]
        else:
            backend = 'anydbm'
        # FIXME: i'd like to have an option to abort the tracker creation
        #   say, by entering a single dot.  but i cannot think of
        #   appropriate prompt for that.
        home = raw_input(
            _('Enter directory path to create demo tracker [%s]: ') % home)
        if not home:
            home = DEFAULT_HOME
        templates = admin.AdminTool().listTemplates().keys()
        template = raw_input(
            _('Enter tracker template to use (one of (%s)) [%s]: ') %
            (','.join(templates),template))
        if not template:
            template = DEFAULT_TEMPLATE
        # install
        demo.install_demo(home, backend,
            admin.AdminTool().listTemplates()[template]['path'])
    # run
    demo.run_demo(home)
Exemple #6
0
 def setorderprop(self, orderprop):
     """Set the order property. Used for override of orderprop
        resolution order
     """
     if orderprop not in self.getprops():
         raise ValueError, _("Not a property name: %s") % orderprop
     self._orderprop = orderprop
Exemple #7
0
def run():
    home = DEFAULT_HOME
    template = DEFAULT_TEMPLATE
    nuke = sys.argv[-1] == 'nuke'
    # if there is no tracker in home, force nuke
    try:
        instance.open(home)
    except configuration.NoConfigError:
        nuke = 1
    # if we are to create the tracker, prompt for home
    if nuke:
        if len(sys.argv) > 2:
            backend = sys.argv[-2]
        else:
            backend = 'anydbm'
        # FIXME: i'd like to have an option to abort the tracker creation
        #   say, by entering a single dot.  but i cannot think of
        #   appropriate prompt for that.
        home = my_input(
            _('Enter directory path to create demo tracker [%s]: ') % home)
        if not home:
            home = DEFAULT_HOME
        templates = admin.AdminTool().listTemplates().keys()
        template = my_input(
            _('Enter tracker template to use (one of (%s)) [%s]: ') %
            (','.join(templates),template))
        if not template:
            template = DEFAULT_TEMPLATE
        # install
        demo.install_demo(home, backend,
            admin.AdminTool().listTemplates()[template]['path'])
    # run
    demo.run_demo(home)
Exemple #8
0
def setuid(user):
    if not hasattr(os, 'getuid'):
        return

    # People can remove this check if they're really determined
    if user is None:
        if os.getuid():
            return
        raise ValueError(_("Can't run as root!"))

    if os.getuid():
        print(_('WARNING: ignoring "-u" argument, not root'))
        return

    try:
        import pwd
    except ImportError:
        raise ValueError(_("Can't change users - no pwd module"))
    try:
        try:
            uid = int(user)
        except ValueError:
            uid = pwd.getpwnam(user)[2]
        else:
            pwd.getpwuid(uid)
    except KeyError:
        raise ValueError(_("User %(user)s doesn't exist") % locals())
    os.setuid(uid)
def run():
    # return unless command line arguments contain single directory path
    if (len(sys.argv) != 2) or (sys.argv[1] in ("-h", "--help")):
        print _("Usage: %(program)s <tracker home>") % {"program": sys.argv[0]}
        return
    # collect file paths of html templates
    home = os.path.abspath(sys.argv[1])
    htmldir = os.path.join(home, "html")
    if os.path.isdir(htmldir):
        # glob is not used because i want to match file names
        # without case sensitivity, and that is easier done this way.
        htmlfiles = [filename for filename in os.listdir(htmldir)
            if os.path.isfile(os.path.join(htmldir, filename))
            and filename.lower().endswith(".html")]
    else:
        htmlfiles = []
    # return if no html files found
    if not htmlfiles:
        print _("No tracker templates found in directory %s") % home
        return
    # change to locale dir to have relative source references
    locale = os.path.join(home, "locale")
    if not os.path.isdir(locale):
        os.mkdir(locale)
    os.chdir(locale)
    # tweak sys.argv as this is the only way to tell talgettext what to do
    # Note: unix-style paths used instead of os.path.join deliberately
    sys.argv[1:] = ["-o", TEMPLATE_FILE] \
        + ["../html/" + filename for filename in htmlfiles]
    # run
    talgettext.main()
Exemple #10
0
def rawToHyperdb(db, klass, itemid, propname, value, **kw):
    ''' Convert the raw (user-input) value to a hyperdb-storable value. The
        value is for the "propname" property on itemid (may be None for a
        new item) of "klass" in "db".

        The value is usually a string, but in the case of multilink inputs
        it may be either a list of strings or a string with comma-separated
        values.
    '''
    properties = klass.getprops()

    # ensure it's a valid property name
    propname = propname.strip()
    try:
        proptype =  properties[propname]
    except KeyError:
        raise HyperdbValueError, _('%r is not a property of %s')%(propname,
            klass.classname)

    # if we got a string, strip it now
    if isinstance(value, type('')):
        value = value.strip()

    # convert the input value to a real property value
    value = proptype.from_raw(value, db=db, klass=klass,
        propname=propname, itemid=itemid, **kw)

    return value
def run():
    # return unless command line arguments contain single directory path
    if (len(sys.argv) != 2) or (sys.argv[1] in ("-h", "--help")):
        print _("Usage: %(program)s <tracker home>") % {"program": sys.argv[0]}
        return
    # collect file paths of html templates
    home = os.path.abspath(sys.argv[1])
    htmldir = os.path.join(home, "html")
    if os.path.isdir(htmldir):
        # glob is not used because i want to match file names
        # without case sensitivity, and that is easier done this way.
        htmlfiles = [
            filename for filename in os.listdir(htmldir)
            if os.path.isfile(os.path.join(htmldir, filename))
            and filename.lower().endswith(".html")
        ]
    else:
        htmlfiles = []
    # return if no html files found
    if not htmlfiles:
        print _("No tracker templates found in directory %s") % home
        return
    # change to locale dir to have relative source references
    locale = os.path.join(home, "locale")
    if not os.path.isdir(locale):
        os.mkdir(locale)
    os.chdir(locale)
    # tweak sys.argv as this is the only way to tell talgettext what to do
    # Note: unix-style paths used instead of os.path.join deliberately
    sys.argv[1:] = ["-o", TEMPLATE_FILE] \
        + ["../html/" + filename for filename in htmlfiles]
    # run
    talgettext.main()
Exemple #12
0
 def setlabelprop(self, labelprop):
     """Set the label property. Used for override of labelprop
        resolution order.
     """
     if labelprop not in self.getprops():
         raise ValueError, _("Not a property name: %s") % labelprop
     self._labelprop = labelprop
Exemple #13
0
def loadTemplateInfo(path):
    ''' Attempt to load a Roundup template from the indicated directory.

        Return None if there's no template, otherwise a template info
        dictionary.
    '''
    tif = os.path.join(path, 'TEMPLATE-INFO.txt')
    if not os.path.exists(tif):
        return None

    if os.path.exists(os.path.join(path, 'config.py')):
        print _("WARNING: directory '%s'\n"
            "\tcontains old-style template - ignored"
            ) % os.path.abspath(path)
        return None

    # load up the template's information
    try:
        f = open(tif)
        m = email.parser.Parser().parse(f, True)
        ti = {}
        ti['name'] = m['name']
        ti['description'] = m['description']
        ti['intended-for'] = m['intended-for']
        ti['path'] = path
    finally:
        f.close()
    return ti
Exemple #14
0
def splitDesignator(designator, dre=re.compile(r'([^\d]+)(\d+)')):
    ''' Take a foo123 and return ('foo', 123)
    '''
    m = dre.match(designator)
    if m is None:
        raise DesignatorError, _('"%s" not a node designator')%designator
    return m.group(1), m.group(2)
Exemple #15
0
 def setlabelprop(self, labelprop):
     """Set the label property. Used for override of labelprop
        resolution order.
     """
     if labelprop not in self.getprops():
         raise ValueError, _("Not a property name: %s") % labelprop
     self._labelprop = labelprop
Exemple #16
0
 def setorderprop(self, orderprop):
     """Set the order property. Used for override of orderprop
        resolution order
     """
     if orderprop not in self.getprops():
         raise ValueError, _("Not a property name: %s") % orderprop
     self._orderprop = orderprop
Exemple #17
0
def splitDesignator(designator, dre=re.compile(r'([^\d]+)(\d+)')):
    ''' Take a foo123 and return ('foo', 123)
    '''
    m = dre.match(designator)
    if m is None:
        raise DesignatorError, _('"%s" not a node designator') % designator
    return m.group(1), m.group(2)
Exemple #18
0
    def get_server(self):
        """Return HTTP server object to run"""
        # we don't want the cgi module interpreting the command-line args ;)
        sys.argv = sys.argv[:1]

        # preload all trackers unless we are in "debug" mode
        tracker_homes = self.trackers()
        if self["MULTIPROCESS"] == "debug":
            trackers = None
        else:
            trackers = dict([(name, roundup.instance.open(home, optimize=1))
                for (name, home) in tracker_homes])

        # build customized request handler class
        class RequestHandler(RoundupRequestHandler):
            LOG_IPADDRESS = not self["LOG_HOSTNAMES"]
            TRACKER_HOMES = dict(tracker_homes)
            TRACKERS = trackers
            DEBUG_MODE = self["MULTIPROCESS"] == "debug"
            CONFIG = self

        if self["SSL"]:
            base_server = SecureHTTPServer
        else:
            base_server = BaseHTTPServer.HTTPServer

        # obtain request server class
        if self["MULTIPROCESS"] not in MULTIPROCESS_TYPES:
            print _("Multiprocess mode \"%s\" is not available, "
                "switching to single-process") % self["MULTIPROCESS"]
            self["MULTIPROCESS"] = "none"
            server_class = base_server
        elif self["MULTIPROCESS"] == "fork":
            class ForkingServer(SocketServer.ForkingMixIn,
                base_server):
                    pass
            server_class = ForkingServer
        elif self["MULTIPROCESS"] == "thread":
            class ThreadingServer(SocketServer.ThreadingMixIn,
                base_server):
                    pass
            server_class = ThreadingServer
        else:
            server_class = base_server

        # obtain server before changing user id - allows to
        # use port < 1024 if started as root
        try:
            args = ((self["HOST"], self["PORT"]), RequestHandler)
            kwargs = {}
            if self["SSL"]:
                kwargs['ssl_pem'] = self["PEM"]
            httpd = server_class(*args, **kwargs)
        except socket.error, e:
            if e[0] == errno.EADDRINUSE:
                raise socket.error, \
                    _("Unable to bind to port %s, port already in use.") \
                    % self["PORT"]
            raise
Exemple #19
0
 def from_raw(self, value, **kw):
     value = value.strip()
     try:
         value = float(value)
     except ValueError:
         raise HyperdbValueError, _('property %s: %r is not a number')%(
             kw['propname'], value)
     return value
Exemple #20
0
 def timecheck(self, field, delay):
     try:
         created = unpack_timestamp(self.form[field].value)
     except KeyError:
         raise FormError(_("Form is corrupted, missing: %s." % field))
     if time.time() - created < delay:
         raise FormError(_("Responding to form too quickly."))
     return True
Exemple #21
0
 def from_raw(self, value, **kw):
     value = value.strip()
     try:
         value = float(value)
     except ValueError:
         raise HyperdbValueError, _('property %s: %r is not a number') % (
             kw['propname'], value)
     return value
Exemple #22
0
def create_client( ):
	tracker = valid_dir(DBPATH )    
	if not tracker:
		print _("There is no correct roundup data directory!")
		client = None        
	else:	             
		try:
        		client = ajaxClient.Client(instance=tracker)        	
        	except:
        		client = None	        
        return client
Exemple #23
0
def convertLinkValue(db, propname, prop, value, idre=re.compile('^\d+$')):
    ''' Convert the link value (may be id or key value) to an id value. '''
    linkcl = db.classes[prop.classname]
    if not idre.match(value):
        if linkcl.getkey():
            try:
                value = linkcl.lookup(value)
            except KeyError, message:
                raise HyperdbValueError, _('property %s: %r is not a %s.') % (
                    propname, value, prop.classname)
        else:
            raise HyperdbValueError, _('you may only enter ID values '\
                'for property %s')%propname
Exemple #24
0
 def local_user_exists(self):
     """Verify if the given user exists. As a side effect set the
     'client.userid'."""
     # make sure the user exists
     try:
         self.client.userid = self.db.user.lookup(self.client.user)
     except KeyError:
         msg = _("Unknown user '%s'") % self.client.user
         self.LOG.debug("__['%s'", msg)
         self.client.error_message.append(
             _("Unknown user  '%s'") % self.client.user)
         return False
     return True
Exemple #25
0
def convertLinkValue(db, propname, prop, value, idre=re.compile('^\d+$')):
    ''' Convert the link value (may be id or key value) to an id value. '''
    linkcl = db.classes[prop.classname]
    if not idre.match(value):
        if linkcl.getkey():
            try:
                value = linkcl.lookup(value)
            except KeyError, message:
                raise HyperdbValueError, _('property %s: %r is not a %s.')%(
                    propname, value, prop.classname)
        else:
            raise HyperdbValueError, _('you may only enter ID values '\
                'for property %s')%propname
Exemple #26
0
def setuid(user):
    if not hasattr(os, 'getuid'):
        return

    # People can remove this check if they're really determined
    if user is None:
        if os.getuid():
            return
        raise ValueError, _("Can't run as root!")

    if os.getuid():
        print _('WARNING: ignoring "-u" argument, not root')
        return

    try:
        import pwd
    except ImportError:
        raise ValueError, _("Can't change users - no pwd module")
    try:
        try:
            uid = int(user)
        except ValueError:
            uid = pwd.getpwnam(user)[2]
        else:
            pwd.getpwuid(uid)
    except KeyError:
        raise ValueError, _("User %(user)s doesn't exist")%locals()
    os.setuid(uid)
Exemple #27
0
    def index(self):
        ''' Print up an index of the available trackers
        '''
        keys = list(self.TRACKER_HOMES.keys())
        if len(keys) == 1:
            self.send_response(302)
            self.send_header('Location', urllib_.quote(keys[0]) + '/index')
            self.end_headers()
        else:
            self.send_response(200)

        self.send_header('Content-Type', 'text/html')
        self.end_headers()
        w = self.wfile.write

        if self.CONFIG and self.CONFIG['TEMPLATE']:
            template = open(self.CONFIG['TEMPLATE']).read()
            pt = PageTemplate()
            pt.write(template)
            extra = { 'trackers': self.TRACKERS,
                'nothing' : None,
                'true' : 1,
                'false' : 0,
            }
            w(s2b(pt.pt_render(extra_context=extra)))
        else:
            w(s2b(_('<html><head><title>Roundup trackers index</title></head>\n'
                    '<body><h1>Roundup trackers index</h1><ol>\n')))
            keys.sort()
            for tracker in keys:
                w(s2b('<li><a href="%(tracker_url)s/index">%(tracker_name)s</a>\n'%{
                    'tracker_url': urllib_.quote(tracker),
                    'tracker_name': html_escape(tracker)}))
            w(b'</ol></body></html>')
Exemple #28
0
 def cache_db_type(self, path):
     ''' determine which DB wrote the class file, and cache it as an
         attribute of __class__ (to allow for subclassed DBs to be
         different sorts)
     '''
     db_type = ''
     if os.path.exists(path):
         db_type = whichdb.whichdb(path)
         if not db_type:
             raise hyperdb.DatabaseError, \
                 _("Couldn't identify database type")
     elif os.path.exists(path+'.db'):
         # if the path ends in '.db', it's a dbm database, whether
         # anydbm says it's dbhash or not!
         db_type = 'dbm'
     self.__class__._db_type = db_type
Exemple #29
0
    def index(self):
        ''' Print up an index of the available trackers
        '''
        keys = self.TRACKER_HOMES.keys()
        if len(keys) == 1:
            self.send_response(302)
            self.send_header('Location', urllib.quote(keys[0]) + '/index')
            self.end_headers()
        else:
            self.send_response(200)

        self.send_header('Content-Type', 'text/html')
        self.end_headers()
        w = self.wfile.write

        if self.CONFIG and self.CONFIG['TEMPLATE']:
            template = open(self.CONFIG['TEMPLATE']).read()
            pt = PageTemplate()
            pt.write(template)
            extra = { 'trackers': self.TRACKERS,
                'nothing' : None,
                'true' : 1,
                'false' : 0,
            }
            w(pt.pt_render(extra_context=extra))
        else:
            w(_('<html><head><title>Roundup trackers index</title></head>\n'
                '<body><h1>Roundup trackers index</h1><ol>\n'))
            keys.sort()
            for tracker in keys:
                w('<li><a href="%(tracker_url)s/index">%(tracker_name)s</a>\n'%{
                    'tracker_url': urllib.quote(tracker),
                    'tracker_name': cgi.escape(tracker)})
            w('</ol></body></html>')
Exemple #30
0
class NewItemAction(EditCommon):
    def handle(self):
        ''' Add a new item to the database.

            This follows the same form as the EditItemAction, with the same
            special form values.
        '''
        # ensure modification comes via POST
        if self.client.env['REQUEST_METHOD'] != 'POST':
            raise roundup.exceptions.Reject(self._('Invalid request'))

        # parse the props from the form
        try:
            props, links = self.client.parsePropsFromForm(create=1)
        except (ValueError, KeyError), message:
            self.client.add_error_message(self._('Error: %s') % str(message))
            return

        # handle the props - edit or create
        try:
            # when it hits the None element, it'll set self.nodeid
            messages = self._editnodes(props, links)
        except (ValueError, KeyError, IndexError,
                roundup.exceptions.Reject), message:
            # these errors might just be indicative of user dumbness
            self.client.add_error_message(_('Error: %s') % str(message))
            return
Exemple #31
0
 def encrypt_to(self, message, sendto):
     """ Encrypt given message to sendto receivers.
         Returns a new RFC 3156 conforming message.
     """
     plain = gpg.core.Data(message.as_string())
     cipher = gpg.core.Data()
     ctx = gpg.core.Context()
     ctx.set_armor(1)
     keys = []
     for adr in sendto:
         ctx.op_keylist_start(adr, 0)
         # only first key per email
         k = ctx.op_keylist_next()
         if k is not None:
             keys.append(k)
         else:
             msg = _('No key for "%(adr)s" in keyring') % locals()
             raise MessageSendError(msg)
         ctx.op_keylist_end()
     ctx.op_encrypt(keys, 1, plain, cipher)
     cipher.seek(0, 0)
     msg = MIMEMultipart('encrypted',
                         boundary=None,
                         _subparts=None,
                         protocol="application/pgp-encrypted")
     part = MIMEBase('application', 'pgp-encrypted')
     part.set_payload("Version: 1\r\n")
     msg.attach(part)
     part = MIMEBase('application', 'octet-stream')
     part.set_payload(cipher.read())
     msg.attach(part)
     return msg
Exemple #32
0
 def verifyLogin(self, username, password):
     """Verify the login of `username` with `password`. Try first LDAP if
     this is specified as authentication source, and then login against
     local database."""
     self.LOG.debug("username=%s password=%s", username,
                    '*' * len(password))
     authenticated = False
     if not self.use_local_auth:
         self.LOG.debug("LDAP authentication")
         authenticated = self.ldap_login(username, password)
         if authenticated:
             self.LOG.debug("User '%s' authenticated against LDAP.",
                            username)
     if not authenticated:
         self.LOG.debug("Local database authentication")
         authenticated = self.local_login(password)
         if authenticated:
             self.LOG.debug(
                 "User '%s' authenticated against local database.",
                 username)
     if not authenticated:
         msg = _("Could not authenticate user '%s'" % username)
         self.LOG.debug(msg)
         raise exceptions.LoginError, msg
     return authenticated
Exemple #33
0
 def cache_db_type(self, path):
     ''' determine which DB wrote the class file, and cache it as an
         attribute of __class__ (to allow for subclassed DBs to be
         different sorts)
     '''
     db_type = ''
     if os.path.exists(path):
         db_type = whichdb.whichdb(path)
         if not db_type:
             raise hyperdb.DatabaseError, \
                 _("Couldn't identify database type")
     elif os.path.exists(path + '.db'):
         # if the path ends in '.db', it's a dbm database, whether
         # anydbm says it's dbhash or not!
         db_type = 'dbm'
     self.__class__._db_type = db_type
Exemple #34
0
 def encrypt_to(self, message, sendto):
     """ Encrypt given message to sendto receivers.
         Returns a new RFC 3156 conforming message.
     """
     plain = pyme.core.Data(message.as_string())
     cipher = pyme.core.Data()
     ctx = pyme.core.Context()
     ctx.set_armor(1)
     keys = []
     for adr in sendto:
         ctx.op_keylist_start(adr, 0)
         # only first key per email
         k = ctx.op_keylist_next()
         if k is not None:
             keys.append(k)
         else:
             msg = _('No key for "%(adr)s" in keyring')%locals()
             raise MessageSendError, msg
         ctx.op_keylist_end()
     ctx.op_encrypt(keys, 1, plain, cipher)
     cipher.seek(0,0)
     msg = MIMEMultipart('encrypted', boundary=None, _subparts=None,
         protocol="application/pgp-encrypted")
     part = MIMEBase('application', 'pgp-encrypted')
     part.set_payload("Version: 1\r\n")
     msg.attach(part)
     part = MIMEBase('application', 'octet-stream')
     part.set_payload(cipher.read())
     msg.attach(part)
     return msg
    def find(self, wordlist):
        """look up all the words in the wordlist.
           For testing wordlist is actually a list.
           In production, wordlist is a list of a single string
           that is a sqlite MATCH query.

           https://www.sqlite.org/fts5.html#full_text_query_syntax
        """
        if not wordlist:
            return []

        a = self.db.arg  # arg is the token for positional parameters

        # removed filtering of word in wordlist to include only
        # words with:  self.minlength <= len(word) <= self.maxlength

        sql = 'select _class, _itemid, _prop from __fts '\
              'where _textblob MATCH %s' % a

        try:
            # tests supply a multi element word list. Join them.
            self.db.cursor.execute(sql, (" ".join(wordlist),))
        except sqlite.OperationalError as e:
            if 'no such column' in e.args[0]:
                raise IndexerQueryError(
                    _("Search failed. Try quoting any terms that "
                      "include a '-' and retry the search."))
            else:
                raise IndexerQueryError(e.args[0].replace("fts5:",
                                                          "Query error:"))

        return self.db.cursor.fetchall()
    def index(self):
        """ Print up an index of the available trackers
        """
        keys = self.TRACKER_HOMES.keys()
        if len(keys) == 1:
            self.send_response(302)
            self.send_header("Location", urllib.quote(keys[0]) + "/index")
            self.end_headers()
        else:
            self.send_response(200)

        self.send_header("Content-Type", "text/html")
        self.end_headers()
        w = self.wfile.write

        if self.CONFIG and self.CONFIG["TEMPLATE"]:
            template = open(self.CONFIG["TEMPLATE"]).read()
            pt = PageTemplate()
            pt.write(template)
            extra = {"trackers": self.TRACKERS, "nothing": None, "true": 1, "false": 0}
            w(pt.pt_render(extra_context=extra))
        else:
            w(
                _(
                    "<html><head><title>Roundup trackers index</title></head>\n"
                    "<body><h1>Roundup trackers index</h1><ol>\n"
                )
            )
            keys.sort()
            for tracker in keys:
                w(
                    '<li><a href="%(tracker_url)s/index">%(tracker_name)s</a>\n'
                    % {"tracker_url": urllib.quote(tracker), "tracker_name": cgi.escape(tracker)}
                )
            w("</ol></body></html>")
Exemple #37
0
    def local_login(self, password):
        """Try local authentication."""
        self.auth_method = 'localdb'
        if not self.local_user_exists():
            return LOGIN_FAILED
        if not self.verifyPassword(self.client.userid, password):
            msg = _('Invalid password')
            self.LOG.warning("%s for userid=%s", msg, self.client.userid)
            self.client.error_message.append(msg)
            return LOGIN_FAILED

        # Determine whether the user has permission to log in. Base behaviour
        # is to check the user has "Web Access".
        rights = "Web Access"
        if not self.hasPermission(rights):
            msg = _("You do not have permission to login")
            self.LOG.debug("%s, %s, %s", msg, self.client.user, rights)
            raise exceptions.LoginError, msg
        return LOGIN_SUCCEDED
Exemple #38
0
def auto_ssl():
    print _('WARNING: generating temporary SSL certificate')
    import OpenSSL, random
    pkey = OpenSSL.crypto.PKey()
    pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 768)
    cert = OpenSSL.crypto.X509()
    cert.set_serial_number(random.randint(0, sys.maxint))
    cert.gmtime_adj_notBefore(0)
    cert.gmtime_adj_notAfter(60 * 60 * 24 * 365) # one year
    cert.get_subject().CN = '*'
    cert.get_subject().O = 'Roundup Dummy Certificate'
    cert.get_issuer().CN = 'Roundup Dummy Certificate Authority'
    cert.get_issuer().O = 'Self-Signed'
    cert.set_pubkey(pkey)
    cert.sign(pkey, 'md5')
    ctx = SSL.Context(SSL.SSLv23_METHOD)
    ctx.use_privatekey(pkey)
    ctx.use_certificate(cert)

    return ctx
Exemple #39
0
def auto_ssl():
    print _('WARNING: generating temporary SSL certificate')
    import OpenSSL, time, random, sys
    pkey = OpenSSL.crypto.PKey()
    pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 768)
    cert = OpenSSL.crypto.X509()
    cert.set_serial_number(random.randint(0, sys.maxint))
    cert.gmtime_adj_notBefore(0)
    cert.gmtime_adj_notAfter(60 * 60 * 24 * 365)  # one year
    cert.get_subject().CN = '*'
    cert.get_subject().O = 'Roundup Dummy Certificate'
    cert.get_issuer().CN = 'Roundup Dummy Certificate Authority'
    cert.get_issuer().O = 'Self-Signed'
    cert.set_pubkey(pkey)
    cert.sign(pkey, 'md5')
    ctx = SSL.Context(SSL.SSLv23_METHOD)
    ctx.use_privatekey(pkey)
    ctx.use_certificate(cert)

    return ctx
Exemple #40
0
 def from_raw(self, value, **kw):
     if not value:
         return None
     m = password.Password.pwre.match(value)
     if m:
         # password is being given to us encrypted
         p = password.Password()
         p.scheme = m.group(1)
         if p.scheme not in 'SHA crypt plaintext'.split():
             raise HyperdbValueError, \
                     ('property %s: unknown encryption scheme %r') %\
                     (kw['propname'], p.scheme)
         p.password = m.group(2)
         value = p
     else:
         try:
             value = password.Password(value)
         except password.PasswordValueError, message:
             raise HyperdbValueError, \
                     _('property %s: %s')%(kw['propname'], message)
Exemple #41
0
 def from_raw(self, value, **kw):
     if not value:
         return None
     m = password.Password.pwre.match(value)
     if m:
         # password is being given to us encrypted
         p = password.Password()
         p.scheme = m.group(1)
         if p.scheme not in 'SHA crypt plaintext'.split():
             raise HyperdbValueError, \
                     ('property %s: unknown encryption scheme %r') %\
                     (kw['propname'], p.scheme)
         p.password = m.group(2)
         value = p
     else:
         try:
             value = password.Password(value)
         except password.PasswordValueError, message:
             raise HyperdbValueError, \
                     _('property %s: %s')%(kw['propname'], message)
Exemple #42
0
def create_client( ):
	tracker = valid_dir(DBPATH )
	if not tracker:
		PRINT( _("There is no correct roundup data directory!"))
		client = (CONFIG.data_dir, DBPATH)
	else:
		try:
			client = ajaxClient.Client(instance=tracker)
		except:
			client = None

	return client
Exemple #43
0
def setgid(group):
    if group is None:
        return
    if not hasattr(os, 'setgid'):
        return

    # if root, setgid to the running user
    if os.getuid():
        print _('WARNING: ignoring "-g" argument, not root')
        return

    try:
        import grp
    except ImportError:
        raise ValueError, _("Can't change groups - no grp module")
    try:
        try:
            gid = int(group)
        except ValueError:
            gid = grp.getgrnam(group)[2]
        else:
            grp.getgrgid(gid)
    except KeyError:
        raise ValueError,_("Group %(group)s doesn't exist")%locals()
    os.setgid(gid)
Exemple #44
0
class RegisterAction(RegoCommon, EditCommon):
    name = 'register'
    permissionType = 'Create'

    def handle(self):
        """Attempt to create a new user based on the contents of the form
        and then set the cookie.

        Return 1 on successful login.
        """
        # parse the props from the form
        try:
            props, links = self.client.parsePropsFromForm(create=1)
        except (ValueError, KeyError), message:
            self.client.error_message.append(
                self._('Error: %s') % str(message))
            return

        # registration isn't allowed to supply roles
        user_props = props[('user', None)]
        if user_props.has_key('roles'):
            raise exceptions.Unauthorised, self._(
                "It is not permitted to supply roles at registration.")

        # skip the confirmation step?
        if self.db.config['INSTANT_REGISTRATION']:
            # handle the create now
            try:
                # when it hits the None element, it'll set self.nodeid
                messages = self._editnodes(props, links)
            except (ValueError, KeyError, IndexError,
                    roundup.exceptions.Reject), message:
                # these errors might just be indicative of user dumbness
                self.client.error_message.append(_('Error: %s') % str(message))
                return

            # fix up the initial roles
            self.db.user.set(self.nodeid,
                             roles=self.db.config['NEW_WEB_USER_ROLES'])

            # commit now that all the tricky stuff is done
            self.db.commit()

            # finish off by logging the user in
            self.userid = self.nodeid
            return self.finishRego()
Exemple #45
0
class RegisterAction(RegoCommon, EditCommon):
    name = 'register'
    permissionType = 'Register'

    def handle(self):
        """Attempt to create a new user based on the contents of the form
        and then remember it in session.

        Return 1 on successful login.
        """
        # ensure modification comes via POST
        if self.client.env['REQUEST_METHOD'] != 'POST':
            raise roundup.exceptions.Reject(self._('Invalid request'))

        # parse the props from the form
        try:
            props, links = self.client.parsePropsFromForm(create=1)
        except (ValueError, KeyError), message:
            self.client.add_error_message(self._('Error: %s') % str(message))
            return

        # skip the confirmation step?
        if self.db.config['INSTANT_REGISTRATION']:
            # handle the create now
            try:
                # when it hits the None element, it'll set self.nodeid
                messages = self._editnodes(props, links)
            except (ValueError, KeyError, IndexError,
                    roundup.exceptions.Reject), message:
                # these errors might just be indicative of user dumbness
                self.client.add_error_message(_('Error: %s') % str(message))
                return

            # fix up the initial roles
            self.db.user.set(self.nodeid,
                             roles=self.db.config['NEW_WEB_USER_ROLES'])

            # commit now that all the tricky stuff is done
            self.db.commit()

            # finish off by logging the user in
            self.userid = self.nodeid
            return self.finishRego()
Exemple #46
0
    def confirm_registration(self, otk):
        props = self.getOTKManager().getall(otk)
        for propname, proptype in self.user.getprops().items():
            value = props.get(propname, None)
            if value is None:
                pass
            elif isinstance(proptype, hyperdb.Date):
                props[propname] = date.Date(value)
            elif isinstance(proptype, hyperdb.Interval):
                props[propname] = date.Interval(value)
            elif isinstance(proptype, hyperdb.Password):
                props[propname] = password.Password(encrypted=value)

        # tag new user creation with 'admin'
        self.journaltag = 'admin'

        # create the new user
        cl = self.user

        props['roles'] = self.config.NEW_WEB_USER_ROLES
        try:
            # ASSUME:: ValueError raised during create due to key value
            # conflict. I an use message in exception to determine
            # when I should intercept the exception with a more
            # friendly error message. If i18n is used to translate
            # original exception message this will fail and translated
            # text (probably unfriendly) will be used.
            userid = cl.create(**props)
        except ValueError as e:
            username = props['username']
            # Try to make error message less cryptic to the user.
            if str(e) == 'node with key "%s" exists' % username:
                raise ValueError(_("Username '%s' already exists." % username))
            else:
                raise

            # clear the props from the otk database
        self.getOTKManager().destroy(otk)
        # commit cl.create (and otk changes)
        self.commit()

        return userid
Exemple #47
0
class NewItemAction(EditCommon):
    def handle(self):
        ''' Add a new item to the database.

            This follows the same form as the EditItemAction, with the same
            special form values.
        '''
        # parse the props from the form
        try:
            props, links = self.client.parsePropsFromForm(create=1)
        except (ValueError, KeyError), message:
            self.client.error_message.append(
                self._('Error: %s') % str(message))
            return

        # handle the props - edit or create
        try:
            # when it hits the None element, it'll set self.nodeid
            messages = self._editnodes(props, links)
        except (ValueError, KeyError, IndexError,
                roundup.exceptions.Reject), message:
            # these errors might just be indicative of user dumbness
            self.client.error_message.append(_('Error: %s') % str(message))
            return
Exemple #48
0
 def from_raw(self, value, db, **kw):
     try:
         value = date.Date(value, self.offset(db))
     except ValueError, message:
         raise HyperdbValueError, _('property %s: %r is an invalid '\
             'date (%s)')%(kw['propname'], value, message)
def usage(args, message=None):
    if message is not None:
        print(message)
    print(
        _("""Usage: %(program)s [-v] [-c class] [[-C class] -S field=value]* [instance home] [mail source [specification]]

Options:
 -v: print version and exit
 -c: default class of item to create (else the tracker's MAIL_DEFAULT_CLASS)
 -C / -S: see below

The roundup mail gateway may be called in one of the following ways:
 . without arguments. Then the env var ROUNDUP_INSTANCE will be tried.
 . with an instance home as the only argument,
 . with both an instance home and a mail spool file,
 . with an instance home, a mail source type and its specification.

It also supports optional -C and -S arguments that allows you to set a
fields for a class created by the roundup-mailgw. The default class if
not specified is msg, but the other classes: issue, file, user can
also be used. The -S or --set options uses the same
property=value[;property=value] notation accepted by the command line
roundup command or the commands that can be given on the Subject line
of an email message.

It can let you set the type of the message on a per email address basis.

PIPE:
 If there is no mail source specified,
 the mail gateway reads a single message from the standard input
 and submits the message to the roundup.mailgw module.

Mail source "mailbox":
 In this case, the gateway reads all messages from the UNIX mail spool
 file and submits each in turn to the roundup.mailgw module. The file is
 emptied once all messages have been successfully handled. The file is
 specified as:
   mailbox /path/to/mailbox

In all of the following mail source type the username and password
can be stored in a ~/.netrc file. If done so case only the server name
need to be specified on the command-line.

The username and/or password will be prompted for if not supplied on
the command-line or in ~/.netrc.

POP:
 For the mail source "pop", the gateway reads all messages from the POP server
 specified and submits each in turn to the roundup.mailgw module. The
 server is specified as:
    pop username:password@server
 Alternatively, one can omit one or both of username and password:
    pop username@server
    pop server
 are both valid.

POPS:
 Connect to a POP server over ssl. This requires python 2.4 or later.
 This supports the same notation as POP.

APOP:
 Same as POP, but using Authenticated POP:
    apop username:password@server

IMAP:
 Connect to an IMAP server. This supports the same notation as that of
 POP mail.
    imap username:password@server
 It also allows you to specify a specific mailbox other than INBOX using
 this format:
    imap username:password@server mailbox

IMAPS:
 Connect to an IMAP server over ssl.
 This supports the same notation as IMAP.
    imaps username:password@server [mailbox]

IMAPS_CRAM:
 Connect to an IMAP server over ssl using CRAM-MD5 authentication.
 This supports the same notation as IMAP.
    imaps_cram username:password@server [mailbox]

""") % {'program': args[0]})
    return 1
def main(argv):
    '''Handle the arguments to the program and initialise environment.
    '''
    # take the argv array and parse it leaving the non-option
    # arguments in the args array.
    try:
        optionsList, args = getopt.getopt(argv[1:], 'vc:C:S:',
                                          ['set=', 'class='])
    except getopt.GetoptError:
        # print help information and exit:
        usage(argv)
        sys.exit(2)

    for (opt, _arg) in optionsList:
        if opt == '-v':
            print('%s (python %s)' % (roundup_version, sys.version.split()[0]))
            return

    # figure the instance home
    if len(args) > 0:
        instance_home = args[0]
    else:
        instance_home = os.environ.get('ROUNDUP_INSTANCE', '')
    if not (instance_home and os.path.isdir(instance_home)):
        return usage(argv)

    # get the instance
    import roundup.instance
    instance = roundup.instance.open(instance_home)

    if hasattr(instance, 'MailGW'):
        handler = instance.MailGW(instance, optionsList)
    else:
        handler = mailgw.MailGW(instance, optionsList)

    # if there's no more arguments, read a single message from stdin
    if len(args) == 1:
        return handler.do_pipe()

    # otherwise, figure what sort of mail source to handle
    if len(args) < 3:
        return usage(argv,
                     _('Error: not enough source specification information'))
    source, specification = args[1:3]

    # time out net connections after a minute if we can
    if source not in ('mailbox', 'imaps', 'imaps_cram'):
        if hasattr(socket, 'setdefaulttimeout'):
            socket.setdefaulttimeout(60)

    if source == 'mailbox':
        return handler.do_mailbox(specification)

    # the source will be a network server, so obtain the credentials to
    # use in connecting to the server
    try:
        # attempt to obtain credentials from a ~/.netrc file
        authenticator = netrc.netrc().authenticators(specification)
        username = authenticator[0]
        password = authenticator[2]
        server = specification
        # IOError if no ~/.netrc file, TypeError if the hostname
        # not found in the ~/.netrc file:
    except (IOError, TypeError):
        match = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)',
                         specification)
        if match:
            username = match.group('user')
            password = match.group('pass')
            server = match.group('server')
        else:
            return usage(argv, _('Error: %s specification not valid') % source)

    # now invoke the mailgw handler depending on the server handler requested
    if source.startswith('pop'):
        ssl = source.endswith('s')
        return handler.do_pop(server, username, password, ssl)
    elif source == 'apop':
        return handler.do_apop(server, username, password)
    elif source.startswith('imap'):
        ssl = cram = 0
        if source.endswith('s'):
            ssl = 1
        elif source.endswith('s_cram'):
            ssl = cram = 1
        mailbox = ''
        if len(args) > 3:
            mailbox = args[3]
        return handler.do_imap(server, username, password, mailbox, ssl, cram)

    return usage(
        argv,
        _('Error: The source must be either "mailbox",'
          ' "pop", "pops", "apop", "imap", "imaps" or'
          ' "imaps_cram'))
Exemple #51
0
def usage(message=''):
    if RoundupService:
        os_part = \
""''' -c <Command>  Windows Service options.
               If you want to run the server as a Windows Service, you
               must use configuration file to specify tracker homes.
               Logfile option is required to run Roundup Tracker service.
               Typing "roundup-server -c help" shows Windows Services
               specifics.'''
    else:
        os_part = ""''' -u <UID>      runs the Roundup web server as this UID
 -g <GID>      runs the Roundup web server as this GID
 -d <PIDfile>  run the server in the background and write the server's PID
               to the file indicated by PIDfile. The -l option *must* be
               specified if -d is used.'''
    if message:
        message += '\n'
    print _('''%(message)sUsage: roundup-server [options] [name=tracker home]*

Options:
 -v            print the Roundup version number and exit
 -h            print this text and exit
 -S            create or update configuration file and exit
 -C <fname>    use configuration file <fname>
 -n <name>     set the host name of the Roundup web server instance,
               specifies on which network interfaces to listen for
               connections, defaults to localhost, use 0.0.0.0 to bind
               to all network interfaces
 -p <port>     set the port to listen on (default: %(port)s)
 -l <fname>    log to the file indicated by fname instead of stderr/stdout
 -N            log client machine names instead of IP addresses (much slower)
 -i <fname>    set tracker index template
 -s            enable SSL
 -e <fname>    PEM file containing SSL key and certificate
 -t <mode>     multiprocess mode (default: %(mp_def)s).
               Allowed values: %(mp_types)s.
%(os_part)s

Long options:
 --version          print the Roundup version number and exit
 --help             print this text and exit
 --save-config      create or update configuration file and exit
 --config <fname>   use configuration file <fname>
 All settings of the [main] section of the configuration file
 also may be specified in form --<name>=<value>

Examples:

 roundup-server -S -C /opt/roundup/etc/roundup-server.ini \\
    -n localhost -p 8917 -l /var/log/roundup.log \\
    support=/var/spool/roundup-trackers/support

 roundup-server -C /opt/roundup/etc/roundup-server.ini

 roundup-server support=/var/spool/roundup-trackers/support

 roundup-server -d /var/run/roundup.pid -l /var/log/roundup.log \\
    support=/var/spool/roundup-trackers/support

Configuration file format:
   Roundup Server configuration file has common .ini file format.
   Configuration file created with 'roundup-server -S' contains
   detailed explanations for each option.  Please see that file
   for option descriptions.

How to use "name=tracker home":
   These arguments set the tracker home(s) to use. The name is how the
   tracker is identified in the URL (it's the first part of the URL path).
   The tracker home is the directory that was identified when you did
   "roundup-admin init". You may specify any number of these name=home
   pairs on the command-line. Make sure the name part doesn't include
   any url-unsafe characters like spaces, as these confuse IE.
''') % {
    "message": message,
    "os_part": os_part,
    "port": DEFAULT_PORT,
    "mp_def": DEFAULT_MULTIPROCESS,
    "mp_types": ", ".join(MULTIPROCESS_TYPES),
}
Exemple #52
0
    def get_server(self):
        """Return HTTP server object to run"""
        # we don't want the cgi module interpreting the command-line args ;)
        sys.argv = sys.argv[:1]

        # preload all trackers unless we are in "debug" mode
        tracker_homes = self.trackers()
        if self["MULTIPROCESS"] == "debug":
            trackers = None
        else:
            trackers = dict([(name, roundup.instance.open(home, optimize=1))
                for (name, home) in tracker_homes])

        # build customized request handler class
        class RequestHandler(RoundupRequestHandler):
            LOG_IPADDRESS = not self["LOG_HOSTNAMES"]
            TRACKER_HOMES = dict(tracker_homes)
            TRACKERS = trackers
            DEBUG_MODE = self["MULTIPROCESS"] == "debug"
            CONFIG = self

            def setup(self):
                if self.CONFIG["SSL"]:
                    # perform initial ssl handshake. This will set
                    # internal state correctly so that later closing SSL
                    # socket works (with SSL end-handshake started)
                    self.request.do_handshake()
                RoundupRequestHandler.setup(self)

            def finish(self):
                RoundupRequestHandler.finish(self)
                if self.CONFIG["SSL"]:
                    self.request.shutdown()
                    self.request.close()

        if self["SSL"]:
            base_server = SecureHTTPServer
        else:
            # time out after a minute if we can
            # This sets the socket to non-blocking. SSL needs a blocking
            # socket, so we do this only for non-SSL connections.
            if hasattr(socket, 'setdefaulttimeout'):
                socket.setdefaulttimeout(60)
            base_server = BaseHTTPServer.HTTPServer

        # obtain request server class
        if self["MULTIPROCESS"] not in MULTIPROCESS_TYPES:
            print _("Multiprocess mode \"%s\" is not available, "
                "switching to single-process") % self["MULTIPROCESS"]
            self["MULTIPROCESS"] = "none"
            server_class = base_server
        elif self["MULTIPROCESS"] == "fork":
            class ForkingServer(SocketServer.ForkingMixIn,
                base_server):
                    pass
            server_class = ForkingServer
        elif self["MULTIPROCESS"] == "thread":
            class ThreadingServer(SocketServer.ThreadingMixIn,
                base_server):
                    pass
            server_class = ThreadingServer
        else:
            server_class = base_server

        # obtain server before changing user id - allows to
        # use port < 1024 if started as root
        try:
            args = ((self["HOST"], self["PORT"]), RequestHandler)
            kwargs = {}
            if self["SSL"]:
                kwargs['ssl_pem'] = self["PEM"]
            httpd = server_class(*args, **kwargs)
        except socket.error, e:
            if e[0] == errno.EADDRINUSE:
                raise socket.error, \
                    _("Unable to bind to port %s, port already in use.") \
                    % self["PORT"]
            raise
Exemple #53
0
def main(argv):
    '''Handle the arguments to the program and initialise environment.
    '''
    # take the argv array and parse it leaving the non-option
    # arguments in the args array.
    try:
        optionsList, args = getopt.getopt(argv[1:], 'vc:C:S:', ['set=',
            'class='])
    except getopt.GetoptError:
        # print help information and exit:
        usage(argv)
        sys.exit(2)

    for (opt, arg) in optionsList:
        if opt == '-v':
            print '%s (python %s)'%(roundup_version, sys.version.split()[0])
            return

    # figure the instance home
    if len(args) > 0:
        instance_home = args[0]
    else:
        instance_home = os.environ.get('ROUNDUP_INSTANCE', '')
    if not (instance_home and os.path.isdir(instance_home)):
        return usage(argv)

    # get the instance
    import roundup.instance
    instance = roundup.instance.open(instance_home)

    if hasattr(instance, 'MailGW'):
        handler = instance.MailGW(instance, optionsList)
    else:
        handler = mailgw.MailGW(instance, optionsList)

    # if there's no more arguments, read a single message from stdin
    if len(args) == 1:
        return handler.do_pipe()

    # otherwise, figure what sort of mail source to handle
    if len(args) < 3:
        return usage(argv, _('Error: not enough source specification information'))
    source, specification = args[1:3]

    # time out net connections after a minute if we can
    if source not in ('mailbox', 'imaps', 'imaps_cram'):
        if hasattr(socket, 'setdefaulttimeout'):
            socket.setdefaulttimeout(60)

    if source == 'mailbox':
        return handler.do_mailbox(specification)

    # the source will be a network server, so obtain the credentials to
    # use in connecting to the server
    try:
        # attempt to obtain credentials from a ~/.netrc file
        authenticator = netrc.netrc().authenticators(specification)
        username = authenticator[0]
        password = authenticator[2]
        server = specification
        # IOError if no ~/.netrc file, TypeError if the hostname
        # not found in the ~/.netrc file:
    except (IOError, TypeError):
        match = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)',
                         specification)
        if match:
            username = match.group('user')
            password = match.group('pass')
            server = match.group('server')
        else:
            return usage(argv, _('Error: %s specification not valid') % source)

    # now invoke the mailgw handler depending on the server handler requested
    if source.startswith('pop'):
        ssl = source.endswith('s')
        if ssl and sys.version_info<(2,4):
            return usage(argv, _('Error: a later version of python is required'))
        return handler.do_pop(server, username, password, ssl)
    elif source == 'apop':
        return handler.do_apop(server, username, password)
    elif source.startswith('imap'):
        ssl = cram = 0
        if source.endswith('s'):
            ssl = 1
        elif source.endswith('s_cram'):
            ssl = cram = 1
        mailbox = ''
        if len(args) > 3:
            mailbox = args[3]
        return handler.do_imap(server, username, password, mailbox, ssl,
            cram)

    return usage(argv, _('Error: The source must be either "mailbox",'
        ' "pop", "pops", "apop", "imap", "imaps" or "imaps_cram'))
Exemple #54
0
def usage(args, message=None):
    if message is not None:
        print message
    print _(
"""Usage: %(program)s [-v] [-c class] [[-C class] -S field=value]* [instance home] [mail source [specification]]

Options:
 -v: print version and exit
 -c: default class of item to create (else the tracker's MAIL_DEFAULT_CLASS)
 -C / -S: see below

The roundup mail gateway may be called in one of the following ways:
 . without arguments. Then the env var ROUNDUP_INSTANCE will be tried.
 . with an instance home as the only argument,
 . with both an instance home and a mail spool file,
 . with an instance home, a mail source type and its specification.

It also supports optional -C and -S arguments that allows you to set a
fields for a class created by the roundup-mailgw. The default class if
not specified is msg, but the other classes: issue, file, user can
also be used. The -S or --set options uses the same
property=value[;property=value] notation accepted by the command line
roundup command or the commands that can be given on the Subject line
of an email message.

It can let you set the type of the message on a per email address basis.

PIPE:
 If there is no mail source specified,
 the mail gateway reads a single message from the standard input
 and submits the message to the roundup.mailgw module.

Mail source "mailbox":
 In this case, the gateway reads all messages from the UNIX mail spool
 file and submits each in turn to the roundup.mailgw module. The file is
 emptied once all messages have been successfully handled. The file is
 specified as:
   mailbox /path/to/mailbox

In all of the following mail source type the username and password
can be stored in a ~/.netrc file. If done so case only the server name
need to be specified on the command-line.

The username and/or password will be prompted for if not supplied on
the command-line or in ~/.netrc.

POP:
 For the mail source "pop", the gateway reads all messages from the POP server
 specified and submits each in turn to the roundup.mailgw module. The
 server is specified as:
    pop username:password@server
 Alternatively, one can omit one or both of username and password:
    pop username@server
    pop server
 are both valid.

POPS:
 Connect to a POP server over ssl. This requires python 2.4 or later.
 This supports the same notation as POP.

APOP:
 Same as POP, but using Authenticated POP:
    apop username:password@server

IMAP:
 Connect to an IMAP server. This supports the same notation as that of
 POP mail.
    imap username:password@server
 It also allows you to specify a specific mailbox other than INBOX using
 this format:
    imap username:password@server mailbox

IMAPS:
 Connect to an IMAP server over ssl.
 This supports the same notation as IMAP.
    imaps username:password@server [mailbox]

IMAPS_CRAM:
 Connect to an IMAP server over ssl using CRAM-MD5 authentication.
 This supports the same notation as IMAP.
    imaps_cram username:password@server [mailbox]

""")%{'program': args[0]}
    return 1
Exemple #55
0
def error():
    exc_type, exc_value = sys.exc_info()[:2]
    return _('Error: %s: %s' % (exc_type, exc_value))
Exemple #56
0
 def from_raw(self, value, **kw):
     try:
         value = date.Interval(value)
     except ValueError, message:
         raise HyperdbValueError, _('property %s: %r is an invalid '\
             'date interval (%s)')%(kw['propname'], value, message)
Exemple #57
0
            elif opt != "-c":
                svc_args.extend(opt)
        RoundupService._exe_args_ = " ".join(svc_args)
        # pass the control to serviceutil
        win32serviceutil.HandleCommandLine(RoundupService,
            argv=sys.argv[:1] + args)
        return

    # add tracker names from command line.
    # this is done early to let '--save-config' handle the trackers.
    if args:
        for arg in args:
            try:
                name, home = arg.split('=')
            except ValueError:
                raise ValueError, _("Instances must be name=home")
            config.add_option(TrackerHomeOption(config, "trackers", name))
            config["TRACKERS_" + name.upper()] = home

    # handle remaining options
    if optlist:
        for (opt, arg) in optlist:
            if opt in ("-h", "--help"):
                usage()
            elif opt in ("-v", "--version"):
                print '%s (python %s)' % (roundup_version,
                    sys.version.split()[0])
            elif opt in ("-S", "--save-config"):
                config.save()
                print _("Configuration saved to %s") % config.filepath
        # any of the above options prevent server from running
Exemple #58
0
    def from_raw(self, value, db, klass, propname, itemid, **kw):
        if not value:
            return []

        # get the current item value if it's not a new item
        if itemid and not itemid.startswith('-'):
            curvalue = klass.get(itemid, propname)
        else:
            curvalue = []

        # if the value is a comma-separated string then split it now
        if isinstance(value, type('')):
            value = value.split(',')

        # handle each add/remove in turn
        # keep an extra list for all items that are
        # definitely in the new list (in case of e.g.
        # <propname>=A,+B, which should replace the old
        # list with A,B)
        set = 1
        newvalue = []
        for item in value:
            item = item.strip()

            # skip blanks
            if not item: continue

            # handle +/-
            remove = 0
            if item.startswith('-'):
                remove = 1
                item = item[1:]
                set = 0
            elif item.startswith('+'):
                item = item[1:]
                set = 0

            # look up the value
            itemid = convertLinkValue(db, propname, self, item)

            # perform the add/remove
            if remove:
                try:
                    curvalue.remove(itemid)
                except ValueError:
                    raise HyperdbValueError, _('property %s: %r is not ' \
                        'currently an element')%(propname, item)
            else:
                newvalue.append(itemid)
                if itemid not in curvalue:
                    curvalue.append(itemid)

        # that's it, set the new Multilink property value,
        # or overwrite it completely
        if set:
            value = newvalue
        else:
            value = curvalue

        # TODO: one day, we'll switch to numeric ids and this will be
        # unnecessary :(
        value = [int(x) for x in value]
        value.sort()
        value = [str(x) for x in value]
        return value
Exemple #59
0
def unpack_timestamp(s):
    try:
        timestamp = struct.unpack("i", base64.b64decode(s2b(s)))[0]
    except (struct.error, binascii.Error, TypeError):
        raise FormError(_("Form is corrupted."))
    return timestamp