Ejemplo n.º 1
0
    def __init__(self, hgwebdirconfig=None, cyd=None):
        if cyd is None:
            cyd = cydra.Cydra()

        self.cydra = self.compmgr = cyd
        self.authenticator = HTTPBasicAuthenticator(self.compmgr)

        self.config = config = cyd.config.get_component_config(
            'cydra.repository.hg.HgRepositories', {})
        if 'base' not in config:
            raise Exception("hg base path not configured")

        baseui = None

        if hgwebdirconfig is None:
            hgwebdirconfig = {'/': os.path.join(config['base'], '**')}

            baseui = ui.ui()

            # provide sensible defaults
            baseui.setconfig(
                "web", "allow_archive", "gz, zip, bz2"
            )  #read access -> downloading archive should be fine
            baseui.setconfig("web", "allow_push",
                             "*")  # we are doing access checks, not hg
            baseui.setconfig(
                "web", "push_ssl",
                "false")  # enforcing SSL is left to the user / apache
            baseui.setconfig("web", "encoding", "utf-8")

        self.hgwebdir = hgwebdir(hgwebdirconfig, baseui)
Ejemplo n.º 2
0
    def __init__(self, environ_to_perm, cyd=None):
        """Initialize Authnz helper
        
        :param environ_to_perm: Callable that returns the project or project name and the object an environment corresponds to as a tuple(project, object)"""

        if cyd is None:
            cyd = cydra.Cydra()

        self.cydra = self.compmgr = cyd
        self.environ_to_perm = environ_to_perm
Ejemplo n.º 3
0
Archivo: git.py Proyecto: smanne/cydra
def post_receive_hook():
    """Hook for git"""
    import sys
    import logging
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False)
    (options, args) = parser.parse_args()

    if options.verbose:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.ERROR)

    if len(args) != 2:
        print "Usage: %s <projectname> <reponame>" % sys.argv[0]
        sys.exit(2)

    cyd = cydra.Cydra()
    gitconf = cyd.config.get_component_config(
        'cydra.repository.git.GitRepositories', {})
    gitcommand = gitconf.get('gitcommand', 'git')

    project = cyd.get_project(args[0])

    if not project:
        sys.exit("Unknown project")

    repository = project.get_repository('git', args[1])

    if not repository:
        sys.exit("Unknown repository")

    for line in sys.stdin.readlines():
        old, new, ref = line.split()

        args = [new] if old == '0' * 40 else [new, '^' + old]

        commits = subprocess.Popen(
            [gitcommand, '--git-dir', repository.path, 'rev-list'] + args,
            stdout=subprocess.PIPE).communicate()[0]

        repository.notify_post_commit(commits.splitlines()[::-1])

    sys.exit(0)
Ejemplo n.º 4
0
def sync(args):
    cyd = cydra.Cydra()
    projects = cyd.get_project_names()

    for projectname in projects:
        project = cyd.get_project(projectname)

        if not project:
            print "Unknown Project:", projectname
        else:
            if project.sync():
                print "Synced Project:", projectname
            else:
                print "Synced FAILED:", projectname
Ejemplo n.º 5
0
    def __init__(self, cyd=None):
        if cyd is None:
            cyd = cydra.Cydra()

        self.cydra = self.compmgr = cyd
        self.authenticator = HTTPBasicAuthenticator(self.compmgr)

        self.config = config = cyd.config.get_component_config(
            'cydraplugins.trac.TracEnvironments', {})
        if 'base' not in config:
            raise Exception("trac environments base path not configured")

        os.environ['TRAC_ENV_PARENT_DIR'] = config['base']
        import trac.web.main
        self.trac = trac.web.main.dispatch_request
Ejemplo n.º 6
0
def cmd_project(args):
    if len(args) < 2:
        print "Syntax: project <projectname> <command>"
    else:
        cyd = cydra.Cydra()
        project = cyd.get_project(args[0])

        if project is None:
            print "Unknown Project"
        else:
            cmds = ProjectCmds(cyd, project)

            if not hasattr(cmds, args[1]):
                cmds.help([])
            else:
                getattr(cmds, args[1])(args[2:])
Ejemplo n.º 7
0
Archivo: hg.py Proyecto: smanne/cydra
def commit_hook():
    """Hook for hg"""
    import sys
    import logging
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False)
    (options, args) = parser.parse_args()

    if options.verbose:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.ERROR)

    if len(args) != 3:
        print "Usage: %s <projectname> <reponame> <node>" % sys.argv[0]
        sys.exit(2)

    cyd = cydra.Cydra()
    hgconf = cyd.config.get_component_config(
        'cydra.repository.hg.HgRepositories', {})
    hgcommand = hgconf.get('hgcommand', 'hg')

    project = cyd.get_project(args[0])

    if not project:
        sys.exit("Unknown project")

    repository = project.get_repository('hg', args[1])

    if not repository:
        sys.exit("Unknown repository")

    commits = subprocess.Popen([
        hgcommand, '--repository', repository.path, 'log', '--template',
        '{node}\\n', '--rev', args[2] + ':tip'
    ],
                               stdout=subprocess.PIPE).communicate()[0]
    repository.notify_post_commit(commits.splitlines())
Ejemplo n.º 8
0
def commit_hook():
    """Hook for svn"""
    import sys

    if len(sys.argv) != 4:
        print "Usage: %s <projectname> <reponame> <revision>" % sys.argv[0]
        sys.exit(2)

    cyd = cydra.Cydra()

    project = cyd.get_project(sys.argv[1])

    if not project:
        sys.exit("Unknown project")

    repository = project.get_repository('svn', sys.argv[2])

    if not repository:
        sys.exit("Unknown repository")

    repository.notify_post_commit(sys.argv[3])
Ejemplo n.º 9
0
    def __init__(self, cyd=None, gitviewer=None):
        if cyd is None:
            cyd = cydra.Cydra()

        self.cydra = self.compmgr = cyd
        self.authenticator = HTTPBasicAuthenticator(self.compmgr)
        self.gitviewer = gitviewer

        self.config = config = cyd.config.get_component_config(
            'cydra.repository.git.GitRepositories', {})
        if 'base' not in config:
            raise Exception("git base path not configured")

        self.git_inforefs_handler = GitHTTPBackendInfoRefs(
            content_path=config['base'], uri_marker='')
        self.git_rpc_handler = GitHTTPBackendSmartHTTP(
            content_path=config['base'], uri_marker='')
        self.static_handler = StaticWSGIServer(content_path=config['base'],
                                               uri_marker='')

        self.git_inforefs_handler.repo_auto_create = False
        self.git_rpc_handler.repo_auto_create = False
        self.static_handler.repo_auto_create = False
Ejemplo n.º 10
0
    def __init__(self, cyd=None):
        if cyd is None:
            cyd = cydra.Cydra()

        self.cydra = self.compmgr = cyd
        self.cache = SimpleCache()
Ejemplo n.º 11
0
def run_server():
    import logging
    import logging.handlers
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False)
    parser.add_option('-p',
                      '--proxy',
                      action='store_true',
                      dest='proxy',
                      default=False)
    parser.add_option('-s',
                      '--script-name',
                      action='store',
                      dest='script_name',
                      default=None)
    parser.add_option('-f',
                      '--force-https',
                      action='store_true',
                      dest='force_https',
                      default=False)
    parser.add_option('-d',
                      '--daemonize',
                      action='store_true',
                      dest='daemonize',
                      default=False)
    parser.add_option('-i',
                      '--pidfile',
                      action='store',
                      dest='pidfile',
                      default=None)
    parser.add_option('-l',
                      '--logfile',
                      action='store',
                      dest='logfile',
                      default=None)
    parser.add_option('-u',
                      '--user',
                      action='store',
                      dest='user',
                      default=None)
    parser.add_option('-g',
                      '--group',
                      action='store',
                      dest='group',
                      default=None)
    (options, args) = parser.parse_args()

    # configure logging
    formatter = logging.Formatter(
        '[%(asctime)s] %(levelname)s: <%(name)s@%(filename)s:%(lineno)d> %(message)s'
    )

    if options.verbose:
        loglevel = logging.DEBUG
    else:
        loglevel = logging.ERROR

    if options.logfile:
        handler = logging.handlers.TimedRotatingFileHandler(options.logfile,
                                                            when='midnight',
                                                            backupCount=7,
                                                            encoding='utf-8')
    else:
        handler = logging.StreamHandler()

    handler.setFormatter(formatter)
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(loglevel)

    port = 8080
    if len(args) > 0:
        port = int(args[0])

    cyd = cydra.Cydra()
    helper = CydraHelper(cyd)
    wsgiapp = cydraplugins.githttp.create_application(cyd=cyd)
    if options.proxy:
        wsgiapp = ProxyHelper(wsgiapp)

        if options.script_name:
            wsgiapp.script_name = options.script_name

        if options.force_https:
            wsgiapp.force_https = True

    fallbackapp = tornado.wsgi.WSGIContainer(wsgiapp)
    app = tornado.web.Application([
        ('/.*/.*/git-.*', RPCHandler, helper.config_dict),
        ('/.*/.*/info/refs', InfoRefsHandler, helper.config_dict),
        ('/.*/.*/HEAD', FileHandler, helper.config_dict),
        ('/.*/.*/objects/.*', FileHandler, helper.config_dict),
        ('.*', tornado.web.FallbackHandler, {
            'fallback': fallbackapp
        })
    ])

    sockets = tornado.netutil.bind_sockets(port)

    # daemonize if requested
    if options.daemonize:
        if not options.logfile:
            print "Error: Cannot log to stderr, please specify a log file"
            return

        import daemon, grp, pwd, lockfile

        files = sockets + [handler.stream]

        if options.pidfile:
            pidf = open(options.pidfile, 'w')
            files.append(pidf)

        args = dict(files_preserve=files)

        #if options.pidfile:
        #    args['pidfile'] = PidFile(pidf)

        if options.group:
            if options.group.isdigit():
                args['gid'] = int(options.group)
            else:
                args['gid'] = grp.getgrnam(options.group).gr_gid
        elif os.getgid() == 0:
            args['gid'] = grp.getgrnam('www-data').gr_gid

        if options.user:
            if options.user.isdigit():
                args['uid'] = int(options.user)
            else:
                args['uid'] = pwd.getpwnam(options.user).pw_uid
        elif os.getuid() == 0:
            args['uid'] = pwd.getpwnam('www-data').pw_uid

        context = daemon.DaemonContext(**args)
        context.open()

        # save pid to file
        if options.pidfile:
            pidf.write(str(os.getpid()))
            pidf.close()

    #tornado.process.fork_processes(0)

    import traceback, signal

    def dump_stack(sig, frame):
        logger.debug("Dumping Stack: \n" +
                     ''.join(traceback.format_stack(frame)))

    signal.signal(signal.SIGUSR1, dump_stack)

    server = tornado.httpserver.HTTPServer(app)
    server.add_sockets(sockets)
    tornado.ioloop.IOLoop.instance().start()
Ejemplo n.º 12
0
def create_app(cyd=None):
    """Create the web interface WSGI application"""

    if cyd is None:
        cyd = cydra.Cydra()

    from flask import Flask
    from flaskext.csrf import csrf
    from cydra.web.themes import IThemeProvider, ThemedTemplateLoader, patch_static

    app = Flask(__name__)

    # register themes
    theme_providers = ExtensionPoint(IThemeProvider, component_manager=cyd)
    app.config['cydra_themes'] = dict([(theme.name, theme) for theme in theme_providers.get_themes()])

    default_theme = cyd.config.get('web').get('default_theme')
    if default_theme is not None and default_theme in app.config['cydra_themes']:
        default_theme = app.config['cydra_themes'][default_theme]
        logger.debug("Default theme: %s", default_theme.name)
    else:
        default_theme = None
    theme_detector = ThemeDetector(default_theme)
    app.before_request(theme_detector)

    # replace default loader
    app.jinja_options = Flask.jinja_options.copy()
    app.jinja_options['loader'] = ThemedTemplateLoader(app)

    # patch static file resolver
    patch_static(app)

    # secret key for cookies
    app.secret_key = os.urandom(24)

    # consider the cydra instance to be a form of configuration
    # and therefore store it in the config dict.
    app.config['cydra'] = cyd

    # common views
    app.add_url_rule('/login', 'login', login)

    # Add shorthands to context
    app.context_processor(add_shorthands_to_context)

    # load frontend and backend
    from cydra.web.frontend import blueprint as frontend_blueprint
    patch_static(frontend_blueprint, 'frontend')
    #from cydra.web.admin import blueprint as admin_blueprint
    #patch_static(admin_blueprint, 'admin')

    app.register_blueprint(frontend_blueprint)
    #app.register_blueprint(admin_blueprint)

    # load additional blueprints
    pages = ExtensionPoint(IBlueprintProvider, component_manager=cyd)
    for bpprovider in pages:
        bp = bpprovider.get_blueprint()
        patch_static(bp, bp.name)
        app.register_blueprint(bp)

    # some utility template filters
    from cydra.web.filters import filters
    #map(app.template_filter(), filters)
    _ = [app.template_filter()(f) for f in filters]

    # prevent flask from handling exceptions
    app.debug = True

    # add CSRF protection
    csrf(app)

    # wrap in authentication middleware
    from cydra.web.wsgihelper import AuthenticationMiddleware
    app = AuthenticationMiddleware(cyd, app)

    # enable debugging for certain users
    debugusers = cyd.config.get('web').get('debug_users', [])
    if debugusers:
        from cydra.web.debugging import DebuggingMiddleware
        app = DebuggingMiddleware(app, debugusers)

    return app
Ejemplo n.º 13
0
    def __init__(self):
        self.log.debug('CydraPolicy initializing')

        self.cydra = cydra.Cydra() # DO NOT set compmgr to cydra as this is a Trac component!
Ejemplo n.º 14
0
def run_server():
    import logging
    import logging.handlers
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False)
    parser.add_option('-d',
                      '--daemonize',
                      action='store_true',
                      dest='daemonize',
                      default=False)
    parser.add_option('-i',
                      '--pidfile',
                      action='store',
                      dest='pidfile',
                      default=None)
    parser.add_option('-l',
                      '--logfile',
                      action='store',
                      dest='logfile',
                      default=None)
    parser.add_option('-u',
                      '--user',
                      action='store',
                      dest='user',
                      default=None)
    parser.add_option('-g',
                      '--group',
                      action='store',
                      dest='group',
                      default=None)
    (options, args) = parser.parse_args()

    # configure logging
    formatter = logging.Formatter(
        '[%(asctime)s] %(levelname)s: <%(name)s@%(filename)s:%(lineno)d> %(message)s'
    )

    if options.verbose:
        loglevel = logging.DEBUG
    else:
        loglevel = logging.ERROR

    if options.logfile:
        handler = logging.handlers.TimedRotatingFileHandler(options.logfile,
                                                            when='midnight',
                                                            backupCount=7,
                                                            encoding='utf-8')
    else:
        handler = logging.StreamHandler()

    handler.setFormatter(formatter)
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(loglevel)

    observer = log.PythonLoggingObserver()
    observer.start()

    port = 2222
    if len(args) > 0:
        port = int(args[0])

    cyd = cydra.Cydra()
    helper = CydraHelper(cyd)
    config = cyd.config.get_component_config(
        'cydraplugins.twistedgit.TwistedGit', {})

    keyfilename = config.get('server_key')
    if keyfilename is None:
        # try to find one anyways
        for location in ['cydra', '/etc/cydra']:
            if os.path.exists(location + '.key') and os.path.exists(location +
                                                                    '.pub'):
                keyfilename = location
                break
    if keyfilename is None:
        raise Exception("Failed to find SSH keypair")

    ssh_factory = ssh.create_factory(
        public_keys={'ssh-rsa': keys.Key.fromFile(keyfilename + '.pub')},
        private_keys={'ssh-rsa': keys.Key.fromFile(keyfilename + '.key')},
        authnz=helper,
        git_configuration=helper)

    # daemonize if requested
    if options.daemonize:
        if not options.logfile:
            print "Error: Cannot log to stderr, please specify a log file"
            return

        import daemon, grp, pwd

        files = [handler.stream]

        if options.pidfile:
            pidf = open(options.pidfile, 'w')
            files.append(pidf)

        args = dict(files_preserve=files)

        if options.group:
            if options.group.isdigit():
                args['gid'] = int(options.group)
            else:
                args['gid'] = grp.getgrnam(options.group).gr_gid
        elif os.getgid() == 0:
            args['gid'] = grp.getgrnam('www-data').gr_gid

        if options.user:
            if options.user.isdigit():
                args['uid'] = int(options.user)
            else:
                args['uid'] = pwd.getpwnam(options.user).pw_uid
        elif os.getuid() == 0:
            args['uid'] = pwd.getpwnam('www-data').pw_uid

        context = daemon.DaemonContext(**args)
        context.open()

        # save pid to file
        if options.pidfile:
            pidf.write(str(os.getpid()))
            pidf.close()

    import traceback, signal

    def dump_stack(sig, frame):
        logger.debug("Dumping Stack: \n" +
                     ''.join(traceback.format_stack(frame)))

    signal.signal(signal.SIGUSR1, dump_stack)

    reactor.listenTCP(port, ssh_factory())
    reactor.run()
Ejemplo n.º 15
0
def run_server():
    import logging.handlers
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False)
    parser.add_option('-i',
                      '--pidfile',
                      action='store',
                      dest='pidfile',
                      default=None)
    parser.add_option('-l',
                      '--logfile',
                      action='store',
                      dest='logfile',
                      default=None)
    parser.add_option('-u',
                      '--user',
                      action='store',
                      dest='user',
                      default=None)
    parser.add_option('-g',
                      '--group',
                      action='store',
                      dest='group',
                      default=None)
    parser.add_option('-s',
                      '--sshport',
                      action='store',
                      type='int',
                      dest='sshport',
                      default=2222)
    parser.add_option('-w',
                      '--httpport',
                      action='store',
                      type='int',
                      dest='httpport',
                      default=8080)
    (options, args) = parser.parse_args()

    if (options.user is None) ^ (options.group is None):
        raise Exception("Both user and group have to be specified")

    # configure logging
    formatter = logging.Formatter(
        '[%(asctime)s] %(levelname)s: <%(name)s@%(filename)s:%(lineno)d> %(message)s'
    )

    if options.verbose:
        loglevel = logging.DEBUG
    else:
        loglevel = logging.ERROR

    if options.logfile:
        handler = logging.handlers.TimedRotatingFileHandler(options.logfile,
                                                            when='midnight',
                                                            backupCount=7,
                                                            encoding='utf-8')
    else:
        handler = logging.StreamHandler()

    handler.setFormatter(formatter)
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(loglevel)

    observer = log.PythonLoggingObserver()
    observer.start()

    cyd = cydra.Cydra()
    helper = CydraHelper(cyd)
    config = cyd.config.get_component_config(
        'cydraplugins.gitserverglue.GitServerGlue', {})

    keyfilename = config.get('server_key')
    if keyfilename is None:
        # try to find one anyways
        for location in ['cydra', '/etc/cydra']:
            if os.path.exists(location + '.key') and os.path.exists(location +
                                                                    '.pub'):
                keyfilename = location
                break
    if keyfilename is None:
        raise Exception("Failed to find SSH keypair")

    ssh_factory = ssh.create_factory(
        public_keys={'ssh-rsa': keys.Key.fromFile(keyfilename + '.pub')},
        private_keys={'ssh-rsa': keys.Key.fromFile(keyfilename + '.key')},
        authnz=helper,
        git_configuration=helper)

    http_factory = http.create_factory(authnz=helper,
                                       git_configuration=helper,
                                       git_viewer=find_git_viewer())

    # save pid to file if requested
    if options.pidfile:
        with open(options.pidfile) as pidf:
            pidf.write(str(os.getpid()))

    try:

        def dump_stack(sig, frame):
            logger.debug("Dumping Stack: \n" +
                         ''.join(traceback.format_stack(frame)))

        signal.signal(signal.SIGUSR1, dump_stack)

        reactor.listenTCP(options.sshport, ssh_factory)
        reactor.listenTCP(options.httpport, http_factory)

        # drop privileges if requested
        if os.getuid() == 0 and options.user:
            uid = int(
                options.user) if options.user.isdigit() else pwd.getpwnam(
                    options.user).pw_uid
            gid = int(
                options.group) if options.group.isdigit() else grp.getgrnam(
                    options.group).gr_gid

            os.setgroups([])
            os.setgid(gid)
            os.setuid(uid)

        reactor.run()
    except Exception:
        logger.exception("Caught exception during run")