Example #1
0
def on_load(app):
    if app.id != "syncthing":
        return
    if not users.get_system("syncthing"):
        u = users.SystemUser('syncthing')
        u.add()
    u = users.get_system('syncthing')
    if not os.path.exists("/home/syncthing"):
        os.makedirs("/home/syncthing")
        os.chown("/home/syncthing", u.uid, 100)
    s = services.get("syncthing@syncthing")
    if not s.state == "running":
        s.start()
        count = 0
        while count < 5:
            if not os.path.exists("/home/syncthing/.config/syncthing/config.xml"):
                time.sleep(5)
                count += 1
            else:
                break
    if not os.path.exists("/home/syncthing/.config/syncthing/config.xml"):
        raise Exception("Syncthing taking too long to generate config, try again later")
    global api_key
    api_key = get_api_key()
    global my_id
    my_id = get_myid()
Example #2
0
def create_acme_dummy(domain):
    """
    Create a dummy directory to use for serving ACME challenge data.

    This function is used when no website yet exists for the desired domain.

    :param str domain: Domain name to use
    :returns: Path to directory for challenge data
    """
    site_dir = os.path.join(config.get("websites", "site_dir"),
                            "acme-" + domain)
    challenge_dir = os.path.join(site_dir, ".well-known/acme-challenge")
    conf = nginx.Conf(
        nginx.Server(
            nginx.Key("listen", "80"), nginx.Key("listen", "[::]:80"),
            nginx.Key("server_name", domain), nginx.Key("root", site_dir),
            nginx.Location("/.well-known/acme-challenge/",
                           nginx.Key("root", site_dir))))
    origin = os.path.join("/etc/nginx/sites-available", "acme-" + domain)
    target = os.path.join("/etc/nginx/sites-enabled", "acme-" + domain)
    uid = users.get_system("http").uid
    nginx.dumpf(conf, origin)
    if not os.path.exists(target):
        os.symlink(origin, target)
    if not os.path.exists(challenge_dir):
        os.makedirs(challenge_dir)
    os.chown(site_dir, uid, -1)
    os.chown(os.path.join(site_dir, ".well-known"), uid, -1)
    os.chown(challenge_dir, uid, -1)
    tracked_services.register("acme", domain, domain + "(ACME Validation)",
                              "globe", [('tcp', 80)], 2)
    nginx_reload()
    return challenge_dir
Example #3
0
 def post_restore(self, site, dbpasswd):
     nodejs.install_from_package(site.path, 'production', 
         {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'})
     users.SystemUser("ghost").add()
     uid = users.get_system("ghost").uid
     for r, d, f in os.walk(site.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, -1)
         for x in f:
             os.chown(os.path.join(r, x), uid, -1)
     s = services.get(site.id)
     if s:
         s.remove()
     cfg = {
             'directory': site.path,
             'user': '******',
             'command': 'node %s'%os.path.join(site.path, 'index.js'),
             'autostart': 'true',
             'autorestart': 'true',
             'environment': 'NODE_ENV="production"',
             'stdout_logfile': '/var/log/ghost.log',
             'stderr_logfile': '/var/log/ghost.log'
         }
     s = services.Service(site.id, "supervisor", cfg=cfg)
     s.add()
Example #4
0
    def post_install(self, extra_vars, dbpasswd=""):

        # Make sure the webapps config points to
        # the _site directory and generate it.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = \
                    os.path.join(self.path, '_site')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        s = shell('jekyll build --source {0} --destination {1}'.format(
            self.path, os.path.join(self.path, '_site')))
        if s["code"] != 0:
            raise errors.OperationFailedError(
                'Jekyll failed to build: {0}'.format(str(s["stderr"])))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)

        # Return an explicatory message.
        return 'Jekyll has been setup, with a sample site at {0}. '\
            'Modify these files as you like. To learn how to use Jekyll, '\
            'visit http://jekyllrb.com/docs/usage. After making changes, '\
            'click the site icon to edit, then "Regenerate Site" '\
            'to bring your changes live.'.format(self.path)
Example #5
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Write a basic index file showing that we are here
        if extra_vars.get('php'):
            php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        index_ext = 'php' if extra_vars.get('php') else 'html'
        index_path = os.path.join(self.path, 'index.{0}'.format(index_ext))
        addr = self.domain + (":" + str(self.port) if self.port != 80 else "")
        with open(index_path, 'w') as f:
            f.write(
                '<html>\n'
                '<body>\n'
                '<div style="text-align:center;margin-top:20%;font-family:sans-serif;">\n'
                '<img style="width: 300px;" src="https://cdn.citizenweb.io/static/img/arkos-2-01.png" />\n'
                '<h1>Custom Website</h1>\n'
                '<p>Your site is online at http://{0}, and stored at {0}</p>\n'
                '<p>Feel free to paste your site files there!</p>\n'
                '</div>\n'
                '</body>\n'
                '</html>\n'.format(addr, self.path))

        # Give access to httpd
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #6
0
    def post_install(self, vars, dbpasswd=""):
        # Create Lychee automatic configuration file
        with open(os.path.join(self.path, 'data', 'config.php'), 'w') as f:
            f.write(
                '<?php\n'
                '   if(!defined(\'LYCHEE\')) exit(\'Error: Direct access is allowed!\');\n'
                '   $dbHost = \'localhost\';\n'
                '   $dbUser = \'' + self.db.id + '\';\n'
                '   $dbPassword = \'' + dbpasswd + '\';\n'
                '   $dbName = \'' + self.db.id + '\';\n'
                '   $dbTablePrefix = \'\';\n'
                '?>\n')

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'mysqli', 'gd', 'zip', 'exif', 'json',
                       'mbstring')

        # Rename lychee index.html to index.php to make it work with our default nginx config
        os.rename(os.path.join(self.path, "index.html"),
                  os.path.join(self.path, "index.php"))

        # Finally, make sure that permissions are set so that Lychee
        # can make adjustments and save plugins when need be.
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #7
0
def add_repo(name, dir, ro, perms, vers, rsc, nids=[]):
    config = pull_config()
    folder = {"id": name, "path": dir,
        "readOnly": ro, "ignorePerms": perms, "order": "random",
        "hashers": 0, "lenientMTimes": False, "copiers": 1, "autoNormalize": False,
        "rescanIntervalS": rsc or 60, "devices": [],
        "versioning": {"params": {}, "type": ""}}
    for x in nids:
        folder["devices"].append({"deviceID": x})
    if vers:
        folder["versioning"]["type"] = "simple"
        folder["versioning"]["params"] = {"key": "keep", "val": vers}
    config["folders"].append(folder)
    if dir.startswith('~'):
        dir = os.path.join(os.path.expanduser("~syncthing"), dir.lstrip("~/"))
    if not os.path.exists(dir):
        os.makedirs(dir)
    uid = users.get_system('syncthing').uid
    for r, d, f in os.walk(dir):
        for x in d:
            os.chown(os.path.join(r, x), uid, -1)
        for x in f:
            os.chown(os.path.join(r, x), uid, -1)
    save_config(config)
    return folder
Example #8
0
    def post_install(self, vars, dbpasswd=""):
        # Create Lychee automatic configuration file
        with open(os.path.join(self.path, 'data', 'config.php'), 'w') as f:
            f.write(
                '<?php\n'
                '   if(!defined(\'LYCHEE\')) exit(\'Error: Direct access is allowed!\');\n'
                '   $dbHost = \'localhost\';\n'
                '   $dbUser = \'' + self.db.id + '\';\n'
                '   $dbPassword = \'' + dbpasswd + '\';\n'
                '   $dbName = \'' + self.db.id + '\';\n'
                '   $dbTablePrefix = \'\';\n'
                '?>\n'
            )

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'mysqli', 'gd', 'zip', 'exif', 'json', 'mbstring')

        # Rename lychee index.html to index.php to make it work with our default nginx config
        os.rename(os.path.join(self.path, "index.html"), os.path.join(self.path, "index.php"))

        # Finally, make sure that permissions are set so that Lychee
        # can make adjustments and save plugins when need be.
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #9
0
    def post_install(self, extra_vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' \
            if self.app.selected_dbengine == 'db-mariadb' \
            else 'sqlite'

        # Write a standard Wallabag config file
        config_file = os.path.join(self.path, 'app/config/parameters.yml')
        with open(config_file + ".dist", 'r') as f:
            ic = f.readlines()
        with open(config_file, 'w') as f:
            for l in ic:
                if "database_driver: " in l:
                    pdo = "pdo_mysql" if dbengine == "mysql" else "pdo_sqlite"
                    l = "    database_driver: {0}\n".format(pdo)
                elif "database_path: " in l and dbengine == 'sqlite':
                    l = "    database_path: {0}\n".format(self.db.path)
                elif "database_name: " in l and dbengine == 'mysql':
                    l = "    database_name: {0}\n".format(self.db.id)
                elif "database_user: "******"    database_user: {0}\n".format(self.db.id)
                elif "database_password: "******"{0}"\n'.format(dbpasswd)
                elif "secret: " in l:
                    l = "    secret: {0}\n".format(secret_key)
                f.write(l)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('sqlite3', 'bcmath',
                       'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                       'zip', 'tidy')
        php.open_basedir('add', '/usr/bin/php')

        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'sqlite3':
            php.open_basedir('add', '/var/lib/sqlite3')

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("php bin/console wallabag:install --env=prod -n")
        if s["code"] != 0:
            logger.error("Websites", s["stderr"].decode())
            raise errors.OperationFailedError(
                "Failed to populate database. See logs for more info")
        os.chdir(cwd)

        if dbengine == 'sqlite3':
            os.chown("/var/lib/sqlite3/{0}.db".format(self.db.id), -1, gid)
            os.chmod("/var/lib/sqlite3/{0}.db".format(self.db.id), 0o660)

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #10
0
    def post_install(self, extra_vars, dbpasswd=""):
        secret_key = random_string()

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = requests.get(
                'https://api.wordpress.org/secret-key/1.1/salt/').text
        except:
            keysection = ''
        if 'define(\'AUTH_KEY' not in keysection:
            keysection = (
                'define(\'AUTH_KEY\', \'{0}\');\n'
                'define(\'SECURE_AUTH_KEY\', \'{0}\');\n'
                'define(\'LOGGED_IN_KEY\', \'{0}\');\n'
                'define(\'NONCE_KEY\', \'{0}\');\n'.format(secret_key)
                )

        # Write a standard WordPress config file
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.write('<?php\n'
                    'define(\'DB_NAME\', \'{0}\');\n'
                    'define(\'DB_USER\', \'{0}\');\n'
                    'define(\'DB_PASSWORD\', \'{1}\');\n'
                    'define(\'DB_HOST\', \'localhost\');\n'
                    'define(\'DB_CHARSET\', \'utf8\');\n'
                    'define(\'SECRET_KEY\', \'{2}\');\n'
                    '\n'
                    'define(\'WP_CACHE\', true);\n'
                    'define(\'FORCE_SSL_ADMIN\', false);\n'
                    '\n'
                    '{3}'
                    '\n'
                    '$table_prefix = \'wp_\';\n'
                    '\n'
                    '/** Absolute path to the WordPress directory. */\n'
                    'if ( !defined(\'ABSPATH\') )\n'
                    '   define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                    '\n'
                    '/** Sets up WordPress vars and included files. */\n'
                    'require_once(ABSPATH . \'wp-settings.php\');\n'
                    .format(self.db.id, dbpasswd, secret_key, keysection)
                    )

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysqli', 'opcache')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #11
0
 def post_restore(self, site, dbpasswd):
     nodejs.install_from_package(site.path)
     users.SystemUser("haste").add()
     uid = users.get_system("haste").uid
     for r, d, f in os.walk(site.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, -1)
         for x in f:
             os.chown(os.path.join(r, x), uid, -1)
     services.get(site.id).enable()
def add(id, user, type):
    uid, gid = users.get_system("radicale").uid, groups.get_system("radicale").gid
    try:
        os.makedirs('/home/radicale/.config/radicale/collections/%s' % user)
        os.chown('/home/radicale/.config/radicale/collections', uid, gid)
    except os.error:
        pass
    with open(os.path.join('/home/radicale/.config/radicale/collections', user, id+type), 'w') as f:
        f.write("")
    os.chown(os.path.join('/home/radicale/.config/radicale/collections', user, id+type), uid, gid)
Example #13
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Get around top-level zip restriction (FIXME 0.7.2)
        if "paperwork-master" in os.listdir(self.path):
            tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp"))
            os.rename(os.path.join(self.path, "paperwork-master/frontend"),
                      tmp_path)
            os.rename(os.path.join(self.path, ".arkos"),
                      os.path.join(tmp_path, ".arkos"))
            shutil.rmtree(self.path)
            os.rename(tmp_path, self.path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        dbstr = "mysql, localhost, 3389, {0}, {1}, {0}"\
            .format(self.id, dbpasswd)
        with open(os.path.join(self.path, 'app/storage/db_settings'),
                  'w') as f:
            f.write(dbstr)

        php.composer_install(self.path)
        nodejs.install("gulp", as_global=True)
        nodejs.install_from_package(self.path, stat=None)

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("bower install --allow-root", stdin='y\n')
        if s["code"] != 0:
            raise Exception("Failed to run bower: {0}".format(s["stderr"]))
        s = shell("gulp")
        if s["code"] != 0:
            raise Exception("Failed to run gulp: {0}".format(s["stderr"]))
        s = shell("php artisan migrate --force")
        if s["code"] != 0:
            raise Exception("Failed to run artisan: {0}".format(s["stderr"]))
        os.chdir(cwd)

        # Make sure the webapps config points to the public directory.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = \
                    os.path.join(self.path, 'public')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(os.path.join(self.path, 'app')):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)
        if os.path.exists(os.path.join(self.path, 'app/storage/setup')):
            os.unlink(os.path.join(self.path, 'app/storage/setup'))
Example #14
0
 def put(self, path):
     data = json.loads(request.data)["file"]
     if not os.path.exists(data["path"]):
         abort(404)
     if data["operation"] == "copy":
         if os.path.exists(os.path.join(data["newdir"], data["name"])):
             data["name"] = data["name"]+"-copy"
         if os.path.isdir(data["path"]):
             shutil.copytree(data["path"], os.path.join(data["newdir"], data["name"]))
         else:
             shutil.copy2(data["path"], os.path.join(data["newdir"], data["name"]))
         return jsonify(file=as_dict(os.path.join(data["newdir"], data["name"])))
     elif data["operation"] == "rename":
         shutil.move(data["path"], os.path.join(os.path.split(join(data["path"]))[0], data["name"]))
     elif data["operation"] == "edit":
         with open(data["path"], "w") as f:
             f.write(data["data"])
         return jsonify(file=as_dict(data["path"]))
     elif data["operation"] == "props":
         orig = as_dict(data["path"])
         if data["user"] != orig["user"] or data["group"] != orig["group"]:
             uid, gid = None, None
             u, g = users.get_system(data["user"]), groups.get_system(data["group"])
             if data["user"] == "root":
                 uid = 0
             if data["group"] == "root":
                 gid = 0
             if u and g:
                 uid, gid = u.uid, g.gid
             if uid == None or gid == None:
                 resp = jsonify(message="Invalid user/group specification")
                 resp.status_code = 422
                 return resp
             if data["folder"]:
                 os.chown(data["path"], uid, gid)
                 for r, d, f in os.walk(data["path"]):
                     for x in d:
                         os.chown(os.path.join(r, x), uid, gid)
                     for x in f:
                         os.chown(os.path.join(r, x), uid, gid)
             else:
                 os.chown(data["path"], u.uid, g.gid)
         if data["perms"]["oct"] != orig["perms"]["oct"]:
             if data["folder"]:
                 os.chmod(data["path"], int(data["perms"]["oct"][1:], 8))
                 for r, d, f in os.walk(data["path"]):
                     for x in d:
                         os.chmod(os.path.join(r, x), int(data["perms"]["oct"][1:], 8))
                     for x in f:
                         os.chmod(os.path.join(r, x), int(data["perms"]["oct"][1:], 8))
             else:
                 os.chmod(data["path"], int(data["perms"]["oct"][1:], 8))
         return jsonify(file=as_dict(data["path"]))
     else:
         abort(422)
 def update(self, pkg, ver):
     # General update procedure
     shell('unzip -o -d %s %s' % (self.path, pkg))
     uid = users.get_system("ghost").uid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, -1)
         for x in f:
             os.chown(os.path.join(r, x), uid, -1)
     nodejs.install_from_package(self.path, 'production', {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'})
     services.get(self.id).restart()
Example #16
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = urllib.urlopen('https://api.wordpress.org/secret-key/1.1/salt/').read()
        except:
            keysection = ''
        if not 'define(\'AUTH_KEY' in keysection:
            keysection = (
                'define(\'AUTH_KEY\', \''+secret_key+'\');\n'
                'define(\'SECURE_AUTH_KEY\', \''+secret_key+'\');\n'
                'define(\'LOGGED_IN_KEY\', \''+secret_key+'\');\n'
                'define(\'NONCE_KEY\', \''+secret_key+'\');\n'
                )

        # Write a standard WordPress config file
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.write('<?php\n'
                'define(\'DB_NAME\', \''+self.db.id+'\');\n'
                'define(\'DB_USER\', \''+self.db.id+'\');\n'
                'define(\'DB_PASSWORD\', \''+dbpasswd+'\');\n'
                'define(\'DB_HOST\', \'localhost\');\n'
                'define(\'DB_CHARSET\', \'utf8\');\n'
                'define(\'SECRET_KEY\', \''+secret_key+'\');\n'
                '\n'
                'define(\'WP_CACHE\', true);\n'
                'define(\'FORCE_SSL_ADMIN\', false);\n'
                '\n'
                +keysection+
                '\n'
                '$table_prefix = \'wp_\';\n'
                '\n'
                '/** Absolute path to the WordPress directory. */\n'
                'if ( !defined(\'ABSPATH\') )\n'
                '   define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                '\n'
                '/** Sets up WordPress vars and included files. */\n'
                'require_once(ABSPATH . \'wp-settings.php\');\n'
            )

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysqli', 'opcache')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #17
0
    def post_install(self, vars, dbpasswd=""):
        # Get around top-level zip restriction (FIXME 0.7.2)
        if "paperwork-master" in os.listdir(self.path):
            tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp"))
            os.rename(os.path.join(self.path, "paperwork-master/frontend"), tmp_path)
            os.rename(os.path.join(self.path, ".arkos"),
                      os.path.join(tmp_path, ".arkos"))
            shutil.rmtree(self.path)
            os.rename(tmp_path, self.path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        dbstr = "mysql, localhost, 3389, {0}, {1}, {0}".format(self.id, dbpasswd)
        with open(os.path.join(self.path, 'app/storage/db_settings'), 'w') as f:
            f.write(dbstr)

        php.composer_install(self.path)
        nodejs.install("gulp", as_global=True)
        nodejs.install_from_package(self.path, stat=None)

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("bower install --allow-root", stdin='y\n')
        if s["code"] != 0:
            raise Exception("Failed to run bower: %s" % s["stderr"])
        s = shell("gulp")
        if s["code"] != 0:
            raise Exception("Failed to run gulp: %s" % s["stderr"])
        s = shell("php artisan migrate --force")
        if s["code"] != 0:
            raise Exception("Failed to run artisan: %s" % s["stderr"])
        os.chdir(cwd)

        # Make sure the webapps config points to the public directory.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = os.path.join(self.path, 'public')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(os.path.join(self.path, 'app')):
            for x in d:
                os.chmod(os.path.join(r, x), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0644)
                os.chown(os.path.join(r, x), uid, gid)
        if os.path.exists(os.path.join(self.path, 'app/storage/setup')):
            os.unlink(os.path.join(self.path, 'app/storage/setup'))
Example #18
0
 def update(self, pkg, ver):
     # General update procedure
     shell('unzip -o -d {0} {1}'.format(self.path, pkg))
     uid = users.get_system("ghost").uid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, -1)
         for x in f:
             os.chown(os.path.join(r, x), uid, -1)
     nodejs.install_from_package(self.path, 'production', {
         'sqlite': '/usr/bin/sqlite3',
         'python': '/usr/bin/python2'
     })
     services.get(self.id).restart()
Example #19
0
def add(id, user, type):
    uid, gid = users.get_system("radicale").uid, groups.get_system(
        "radicale").gid
    try:
        os.makedirs('/home/radicale/.config/radicale/collections/%s' % user)
        os.chown('/home/radicale/.config/radicale/collections', uid, gid)
    except os.error:
        pass
    with open(
            os.path.join('/home/radicale/.config/radicale/collections', user,
                         id + type), 'w') as f:
        f.write("")
    os.chown(
        os.path.join('/home/radicale/.config/radicale/collections', user,
                     id + type), uid, gid)
Example #20
0
 def regenerate(self):
     path = self.path
     if not path.endswith("_site"):
         path = os.path.join(self.path, "_site")
     s = shell('jekyll build --source '+self.path.split('/_site')[0]+' --destination '+path)
     if s["code"] != 0:
         raise Exception('Jekyll failed to build: %s'%str(s["stderr"]))
     uid, gid = users.get_system("http").uid, groups.get_system("http").gid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chmod(os.path.join(r, x), 0755)
             os.chown(os.path.join(r, x), uid, gid)
         for x in f:
             os.chmod(os.path.join(r, x), 0644)
             os.chown(os.path.join(r, x), uid, gid)
Example #21
0
def on_load(app):
    if app.id != "syncthing":
        return
    if not users.get_system("syncthing"):
        u = users.SystemUser('syncthing')
        u.add()
    u = users.get_system('syncthing')
    if not os.path.exists("/home/syncthing"):
        os.makedirs("/home/syncthing")
        os.chown("/home/syncthing", u.uid, 0o100)
    config_path = "/home/syncthing/.config/syncthing/config.xml"
    s = services.get("syncthing@syncthing")
    if not os.path.exists(config_path) and s.state != "running":
        s.restart()
        count = 0
        while count < 5:
            if not os.path.exists(config_path):
                time.sleep(5)
                count += 1
            else:
                break
        if not os.path.exists(config_path):
            raise Exception("Syncthing taking too long to generate config,"
                            " try again later")
Example #22
0
 def regenerate(self):
     path = self.path
     if not path.endswith("_site"):
         path = os.path.join(self.path, "_site")
     s = shell('jekyll build --source {0} --destination {1}'.format(
         self.path.split('/_site')[0], path))
     if s["code"] != 0:
         raise errors.OperationFailedError(
             'Jekyll failed to build: {0}'.format(str(s["stderr"])))
     uid, gid = users.get_system("http").uid, groups.get_system("http").gid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chmod(os.path.join(r, x), 0o755)
             os.chown(os.path.join(r, x), uid, gid)
         for x in f:
             os.chmod(os.path.join(r, x), 0o644)
             os.chown(os.path.join(r, x), uid, gid)
Example #23
0
    def post_install(self, vars, dbpasswd=""):
        with open(os.path.join(self.path, 'config.js'), 'r') as f:
            d = json.loads(f.read())
        d["port"] = self.backend_port
        if d["storage"]["type"] == "redis":
            d["storage"]["type"] = "file"
            d["storage"]["path"] = "./data"
            if d["storage"].has_key("host"):
                del d["storage"]["host"]
            if d["storage"].has_key("port"):
                del d["storage"]["port"]
            if d["storage"].has_key("db"):
                del d["storage"]["db"]
            if d["storage"].has_key("expire"):
                del d["storage"]["expire"]
        with open(os.path.join(self.path, 'config.js'), 'w') as f:
            f.write(
                json.dumps(d, sort_keys=True, indent=4,
                           separators=(',', ': ')))

        nodejs.install_from_package(self.path)
        users.SystemUser("haste").add()

        # Finally, make sure that permissions are set so that Haste
        # can save its files properly.
        uid = users.get_system("haste").uid
        if not os.path.exists(os.path.join(self.path, 'data')):
            os.mkdir(os.path.join(self.path, 'data'))
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, -1)
            for x in f:
                os.chown(os.path.join(r, x), uid, -1)

        cfg = {
            'directory': self.path,
            'user': '******',
            'command': 'node %s' % os.path.join(self.path, 'server.js'),
            'autostart': 'true',
            'autorestart': 'true',
            'environment': 'NODE_ENV="production"',
            'stdout_logfile': '/var/log/haste.log',
            'stderr_logfile': '/var/log/haste.log'
        }
        s = services.Service(self.id, "supervisor", cfg=cfg)
        s.add()
Example #24
0
    def post_install(self, vars, dbpasswd=""):
        with open(os.path.join(self.path, 'config.js'), 'r') as f:
            d = json.loads(f.read())
        d["port"] = self.backend_port
        if d["storage"]["type"] == "redis":
            d["storage"]["type"] = "file"
            d["storage"]["path"] = "./data"
            if d["storage"].has_key("host"):
                del d["storage"]["host"]
            if d["storage"].has_key("port"):
                del d["storage"]["port"]
            if d["storage"].has_key("db"):
                del d["storage"]["db"]
            if d["storage"].has_key("expire"):
                del d["storage"]["expire"]
        with open(os.path.join(self.path, 'config.js'), 'w') as f:
            f.write(json.dumps(d, sort_keys=True, 
                indent=4, separators=(',', ': ')))

        nodejs.install_from_package(self.path)
        users.SystemUser("haste").add()

        # Finally, make sure that permissions are set so that Haste
        # can save its files properly.
        uid = users.get_system("haste").uid
        if not os.path.exists(os.path.join(self.path, 'data')):
            os.mkdir(os.path.join(self.path, 'data'))
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, -1)
            for x in f:
                os.chown(os.path.join(r, x), uid, -1)
        
        cfg = {
                'directory': self.path,
                'user': '******',
                'command': 'node %s'%os.path.join(self.path, 'server.js'),
                'autostart': 'true',
                'autorestart': 'true',
                'environment': 'NODE_ENV="production"',
                'stdout_logfile': '/var/log/haste.log',
                'stderr_logfile': '/var/log/haste.log'
            }
        s = services.Service(self.id, "supervisor", cfg=cfg)
        s.add()
Example #25
0
    def post_install(self, vars, dbpasswd=""):
        # Write a standard Wikitten config file
        shutil.copy(os.path.join(self.path, 'config.php.example'),
            os.path.join(self.path, 'config.php'))
        with open(os.path.join(self.path, 'config.php'), 'r') as f:
            d = f.read()
        d = d.replace("'My Wiki'", "'%s'" % self.id)

        with open(os.path.join(self.path, 'config.php'), 'w') as f:
            f.write(d)

        # Give access to httpd
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #26
0
    def post_install(self, vars, dbpasswd=""):
        # Write a standard CMS.js config file
        with open(os.path.join(self.path, 'js/config.js'), 'r') as f:
            d = f.read()
        d = d.replace("siteName: 'My Site'", "siteName: 'CMS.js on arkOS'")
        d = d.replace("siteTagline: 'Your site tagline'", "siteTagline: 'Configure js/config.js to your liking'")
        d = d.replace("mode: 'Github'", "mode: 'Server'")

        with open(os.path.join(self.path, 'js/config.js'), 'w') as f:
            f.write(d)

        # Give access to httpd
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #27
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Write a standard CMS.js config file
        with open(os.path.join(self.path, 'js/config.js'), 'r') as f:
            d = f.read()
        d = d.replace("siteName: 'My Site'", "siteName: 'CMS.js on arkOS'")
        d = d.replace("siteTagline: 'Your site tagline'",
                      "siteTagline: 'Configure js/config.js to your liking'")
        d = d.replace("mode: 'Github'", "mode: 'Server'")

        with open(os.path.join(self.path, 'js/config.js'), 'w') as f:
            f.write(d)

        # Give access to httpd
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #28
0
 def add_acme_challenge(self):
     challenge_path = os.path.join(self.path, ".well-known/acme-challenge/")
     confpath = os.path.join("/etc/nginx/sites-available/", self.id)
     uid = users.get_system("http").uid
     block = nginx.loadf(confpath)
     server = block.server
     locations = server.filter("Location", "/.well-known/acme-challenge/")
     if locations:
         server.remove(*locations)
     server.add(
         nginx.Location("/.well-known/acme-challenge/",
                        nginx.Key("root", self.path)))
     nginx.dumpf(block, confpath)
     if not os.path.exists(challenge_path):
         os.makedirs(challenge_path)
     os.chown(self.path, uid, -1)
     os.chown(os.path.join(self.path, ".well-known"), uid, -1)
     os.chown(challenge_path, uid, -1)
     nginx_reload()
     return challenge_path
Example #29
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Write a standard Wikitten config file
        shutil.copy(os.path.join(
                        self.path,
                        'config.php.example'),
                    os.path.join(self.path, 'config.php'))
        with open(os.path.join(self.path, 'config.php'), 'r') as f:
            d = f.read()
        d = d.replace("'My Wiki'", "'{0}'".format(self.id))

        with open(os.path.join(self.path, 'config.php'), 'w') as f:
            f.write(d)

        # Give access to httpd
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        php.open_basedir('add', '/dev')

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        os.makedirs(os.path.join(self.path, "data"))
        os.chown(os.path.join(self.path, "data"), uid, gid)
        if self.data_path == self.path:
            self.data_path = os.path.join(self.path, "data")
        else:
            try:
                os.makedirs(os.path.join(self.data_path))
            except OSError, e:
                if e[0] == 17:
                    pass
                else:
                    raise
            os.chown(os.path.join(self.data_path), uid, gid)
            php.open_basedir('add', self.data_path)
Example #31
0
    def post_install(self, vars, dbpasswd=""):
        # Make sure the webapps config points to the _site directory and generate it.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = os.path.join(self.path, '_site')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        s = shell('jekyll build --source '+self.path+' --destination '+os.path.join(self.path, '_site'))
        if s["code"] != 0:
            raise Exception('Jekyll failed to build: %s'%str(s["stderr"]))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0644)
                os.chown(os.path.join(r, x), uid, gid)

        # Return an explicatory message.
        return 'Jekyll has been setup, with a sample site at '+self.path+'. Modify these files as you like. To learn how to use Jekyll, visit http://jekyllrb.com/docs/usage. After making changes, click the Edit button for the site, then "Regenerate Site" to bring your changes live.'
Example #32
0
def add_repo(name, dirname, ro, perms, vers, rsc, nids=[]):
    config = pull_config()
    folder = {
        "id": name,
        "path": dir,
        "readOnly": ro,
        "ignorePerms": perms,
        "order": "random",
        "hashers": 0,
        "lenientMTimes": False,
        "copiers": 1,
        "autoNormalize": False,
        "rescanIntervalS": rsc or 60,
        "devices": [],
        "versioning": {
            "params": {},
            "type": ""
        }
    }
    for x in nids:
        folder["devices"].append({"deviceID": x})
    if vers:
        folder["versioning"]["type"] = "simple"
        folder["versioning"]["params"] = {"key": "keep", "val": vers}
    config["folders"].append(folder)
    if dirname.startswith('~'):
        dirname = os.path.join(os.path.expanduser("~syncthing"),
                               dirname.lstrip("~/"))
    if not os.path.exists(dir):
        os.makedirs(dir)
    uid = users.get_system('syncthing').uid
    for r, d, f in os.walk(dir):
        for x in d:
            os.chown(os.path.join(r, x), uid, -1)
        for x in f:
            os.chown(os.path.join(r, x), uid, -1)
    save_config(config)
    folder["is_ready"] = True
    return folder
Example #33
0
    def post_install(self, vars, dbpasswd=""):
        # Write a basic index file showing that we are here
        if vars.get('php'):
            php.enable_mod('xcache')

        with open(os.path.join(self.path, 'index.'+('php' if vars.get('php') else 'html')), 'w') as f:
            f.write(
                '<html>\n'
                '<body>\n'
                '<h1>Genesis - Custom Site</h1>\n'
                '<p>Your site is online and available at '+self.path+'</p>\n'
                '<p>Feel free to paste your site files here</p>\n'
                '</body>\n'
                '</html>\n'
                )

        # Give access to httpd
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #34
0
 def update(self, pkg, ver):
     # General update procedure
     if semver.Version.coerce(ver) > semver.Version('2.0.0'):
         raise Exception(
             "Cannot automatically update from 1.x to 2.x. Please see "
             "Wallabag documentation for more information.")
     os.rename(os.path.join(self.path, 'app/config/parameters.yml'),
               '/tmp/_wb_parameters.yml')
     shell('tar xzf {0} -C {1} --strip 1'.format(pkg, self.path))
     os.rename('/tmp/_wb_parameters.yml',
               os.path.join(self.path, 'app/config/parameters.yml'))
     cachepath = os.path.join(self.path, 'var/cache')
     for x in os.listdir(cachepath):
         fpath = os.path.join(cachepath, x)
         if os.path.isdir(fpath):
             shutil.rmtree(fpath)
         else:
             os.unlink(fpath)
     uid, gid = users.get_system("http").uid, groups.get_system("http").gid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, gid)
         for x in f:
             os.chown(os.path.join(r, x), uid, gid)
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        
        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        if not self.data_path.startswith(self.path):
            os.makedirs(os.path.join(self.path, "data"))
            os.chown(os.path.join(self.path, "data"), uid, gid)
            php.open_basedir('add', self.data_path)

        # Create ownCloud automatic configuration file
        with open(os.path.join(self.path, 'config', 'autoconfig.php'), 'w') as f:
            f.write(
                '<?php\n'
                '   $AUTOCONFIG = array(\n'
                '   "adminlogin" => "admin",\n'
                '   "adminpass" => "'+dbpasswd+'",\n'
                '   "dbtype" => "mysql",\n'
                '   "dbname" => "'+self.db.id+'",\n'
                '   "dbuser" => "'+self.db.id+'",\n'
                '   "dbpass" => "'+dbpasswd+'",\n'
                '   "dbhost" => "localhost",\n'
                '   "dbtableprefix" => "",\n'
                '   "directory" => "'+self.data_path+'",\n'
                '   );\n'
                '?>\n'
                )
        os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap',
            'iconv', 'openssl', 'xcache', 'posix')
        
        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        with open('/etc/php/conf.d/xcache.ini', 'w') as f:
            f.writelines(['extension=xcache.so\n',
                'xcache.size=64M\n',
                'xcache.var_size=64M\n',
                'xcache.admin.enable_auth = Off\n',
                'xcache.admin.user = "******"\n',
                'xcache.admin.pass = "******"\n'])
        
        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell("sudo -u http php index.php")
        if s["code"] != 0:
            raise Exception("ownCloud database population failed")
        s = shell("sudo -u http php occ app:enable user_ldap")
        if s["code"] != 0:
            raise Exception("ownCloud LDAP configuration failed")
        os.chdir(mydir)
        
        ldap_sql = ("REPLACE INTO appconfig (appid, configkey, configvalue) VALUES"
            "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
            "('user_ldap', 'ldap_host', 'localhost'),"
            "('user_ldap', 'ldap_port', '389'),"
            "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_tls', '0'),"
            "('user_ldap', 'ldap_display_name', 'cn'),"
            "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount'),"
            "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup'),"
            "('user_ldap', 'ldap_group_display_name', 'cn'),"
            "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'),"
            "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
            "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
            "('user_ldap', 'ldap_quota_def', ''),"
            "('user_ldap', 'ldap_email_attr', 'mail'),"
            "('user_ldap', 'ldap_cache_ttl', '600'),"
            "('user_ldap', 'ldap_configuration_active', '1'),"
            "('user_ldap', 'home_folder_naming_rule', ''),"
            "('user_ldap', 'ldap_backup_host', ''),"
            "('user_ldap', 'ldap_dn', ''),"
            "('user_ldap', 'ldap_agent_password', ''),"
            "('user_ldap', 'ldap_backup_port', ''),"
            "('user_ldap', 'ldap_nocase', ''),"
            "('user_ldap', 'ldap_turn_off_cert_check', ''),"
            "('user_ldap', 'ldap_override_main_server', ''),"
            "('user_ldap', 'ldap_attributes_for_user_search', ''),"
            "('user_ldap', 'ldap_attributes_for_group_search', ''),"
            "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
            "('user_ldap', 'ldap_expert_uuid_attr', '');"
        )
        self.db.execute(ldap_sql, commit=True)
        # TODO set authed user name
        self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');", commit=True)
Example #36
0
    def post_install(self, extra_vars, dbpasswd=""):
        php.open_basedir('add', '/dev')

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        os.makedirs(os.path.join(self.path, "data"))
        os.chown(os.path.join(self.path, "data"), uid, gid)
        if self.data_path == self.path:
            self.data_path = os.path.join(self.path, "data")
        else:
            try:
                os.makedirs(os.path.join(self.data_path))
            except OSError as e:
                if e[0] == 17:
                    pass
                else:
                    raise
            os.chown(os.path.join(self.data_path), uid, gid)
            php.open_basedir('add', self.data_path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('opcache', 'mysql', 'pdo_mysql', 'zip', 'gd', 'ldap',
                       'iconv', 'openssl', 'posix')
        php.enable_mod('apcu', 'apc', config_file="/etc/php/conf.d/apcu.ini")
        php.change_setting('apc.enable_cli',
                           '1',
                           config_file="/etc/php/conf.d/apcu.ini")

        # Make sure php-fpm has the correct settings,
        # otherwise Nextcloud breaks
        with open("/etc/php/php-fpm.conf", "r") as f:
            lines = f.readlines()
        with open("/etc/php/php-fpm.conf", "w") as f:
            for line in lines:
                if ";clear_env = " in line:
                    line = "clear_env = no\n"
                f.write(line)

        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell(('php occ maintenance:install '
                   '--database "mysql" --database-name "{}" '
                   '--database-user "{}" --database-pass "{}" '
                   '--admin-pass "{}" --data-dir "{}"').format(
                       self.db.id, self.db.id, dbpasswd, dbpasswd,
                       self.data_path))
        if s["code"] != 0:
            logger.critical("Nextcloud", s["stderr"])
            raise Exception("Nextcloud database population failed")
        s = shell("php occ app:enable user_ldap")
        if s["code"] != 0:
            logger.critical("Nextcloud", s["stderr"])
            raise Exception("Nextcloud LDAP configuration failed")
        os.chdir(mydir)
        os.chown(os.path.join(self.path, "config/config.php"), uid, gid)

        ldap_sql = ("REPLACE INTO oc_appconfig "
                    "(appid, configkey, configvalue) VALUES"
                    "('core', 'backgroundjobs_mode', 'cron'),"
                    "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
                    "('user_ldap', 'ldap_host', 'localhost'),"
                    "('user_ldap', 'ldap_port', '389'),"
                    "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_base_users', "
                    "'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_base_groups', "
                    "'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_tls', '0'),"
                    "('user_ldap', 'ldap_display_name', 'cn'),"
                    "('user_ldap', 'ldap_userlist_filter', "
                    "'objectClass=mailAccount'),"
                    "('user_ldap', 'ldap_group_filter', "
                    "'objectClass=posixGroup'),"
                    "('user_ldap', 'ldap_group_display_name', 'cn'),"
                    "('user_ldap', 'ldap_group_member_assoc_attribute', "
                    "'uniqueMember'),"
                    "('user_ldap', 'ldap_login_filter', "
                    "'(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
                    "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
                    "('user_ldap', 'ldap_quota_def', ''),"
                    "('user_ldap', 'ldap_email_attr', 'mail'),"
                    "('user_ldap', 'ldap_cache_ttl', '600'),"
                    "('user_ldap', 'ldap_configuration_active', '1'),"
                    "('user_ldap', 'home_folder_naming_rule', ''),"
                    "('user_ldap', 'ldap_backup_host', ''),"
                    "('user_ldap', 'ldap_dn', ''),"
                    "('user_ldap', 'ldap_agent_password', ''),"
                    "('user_ldap', 'ldap_backup_port', ''),"
                    "('user_ldap', 'ldap_nocase', ''),"
                    "('user_ldap', 'ldap_turn_off_cert_check', ''),"
                    "('user_ldap', 'ldap_override_main_server', ''),"
                    "('user_ldap', 'ldap_attributes_for_user_search', ''),"
                    "('user_ldap', 'ldap_attributes_for_group_search', ''),"
                    "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
                    "('user_ldap', 'ldap_expert_uuid_attr', '');")
        self.db.execute(ldap_sql, commit=True)
        self.db.execute("DELETE FROM oc_group_user;", commit=True)
        self.db.execute(
            "INSERT INTO oc_group_user VALUES ('admin','{0}');".format(
                extra_vars.get("nc-admin", "admin")),
            commit=True)

        if not os.path.exists("/etc/cron.d"):
            os.mkdir("/etc/cron.d")
        with open("/etc/cron.d/nc-{0}".format(self.id), "w") as f:
            f.write("*/15 * * * * http php -f {0} > /dev/null 2>&1".format(
                os.path.join(self.path, "cron.php")))

        with open(os.path.join(self.path, "config", "config.php"), "r") as f:
            data = f.read()
        while re.search("\n(\s*('|\")memcache.local.*?\n)", data, re.DOTALL):
            data = data.replace(
                re.search("\n(\s*('|\")memcache.local.*?\n)", data,
                          re.DOTALL).group(1), "")
        data = data.split("\n")
        with open(os.path.join(self.path, "config", "config.php"), "w") as f:
            for x in data:
                if not x.endswith("\n"):
                    x += "\n"
                if x.startswith(");"):
                    f.write("  'memcache.local' => '\OC\Memcache\APCu',\n")
                f.write(x)

        rootcerts = os.path.join(self.data_path,
                                 'data/files_external/rootcerts.crt')
        if os.path.exists(rootcerts):
            os.chown(os.path.join(rootcerts), uid, gid)

        self.site_edited()
Example #37
0
 def put(self, path):
     data = request.get_json()["file"]
     if not os.path.exists(data["path"]):
         abort(404)
     orig = as_dict(data["path"])
     if data["operation"] == "copy":
         if os.path.exists(os.path.join(data["newdir"], data["name"])):
             data["name"] = data["name"] + "-copy"
         if os.path.isdir(data["path"]):
             shutil.copytree(data["path"],
                             os.path.join(data["newdir"], data["name"]))
         else:
             shutil.copy2(data["path"],
                          os.path.join(data["newdir"], data["name"]))
         return jsonify(
             file=as_dict(os.path.join(data["newdir"], data["name"])))
     elif data["operation"] == "rename":
         shutil.move(
             data["path"],
             os.path.join(
                 os.path.split(join(data["path"]))[0], data["name"]))
     elif data["operation"] == "edit":
         with open(data["path"], "w") as f:
             f.write(data["data"])
         return jsonify(file=as_dict(data["path"]))
     elif data["operation"] == "extract":
         if not orig["type"] == "archive":
             return jsonify(errors={"msg": "Not an archive"}), 422
         extract(data["path"], os.path.dirname(data["path"]))
         return jsonify(file=as_dict(data["path"]))
     elif data["operation"] == "props":
         if data["user"] != orig["user"] or data["group"] != orig["group"]:
             uid, gid = None, None
             u, g = users.get_system(data["user"]), groups.get_system(
                 data["group"])
             if data["user"] == "root":
                 uid = 0
             if data["group"] == "root":
                 gid = 0
             if u and g:
                 uid = u.uid if u.uid is not None else -1
                 gid = g.gid if g.gid is not None else -1
             if data["folder"]:
                 os.chown(data["path"], uid, gid)
                 for r, d, f in os.walk(data["path"]):
                     for x in d:
                         os.chown(os.path.join(r, x), uid, gid)
                     for x in f:
                         os.chown(os.path.join(r, x), uid, gid)
             else:
                 os.chown(data["path"], uid, gid)
         if data["perms"]["oct"] != orig["perms"]["oct"]:
             if data["folder"]:
                 os.chmod(data["path"], int(data["perms"]["oct"], 8))
                 for r, d, f in os.walk(data["path"]):
                     for x in d:
                         os.chmod(os.path.join(r, x),
                                  int(data["perms"]["oct"], 8))
                     for x in f:
                         os.chmod(os.path.join(r, x),
                                  int(data["perms"]["oct"], 8))
             else:
                 os.chmod(data["path"], int(data["perms"]["oct"], 8))
         return jsonify(file=as_dict(data["path"]))
     else:
         abort(422)
Example #38
0
def _request_acme_certificate(domain, webroot, nthread):
    nthread.title = "Requesting ACME certificate"
    signals.emit("certificates", "pre_add", id)
    domains = [domain]

    uid = users.get_system("http").uid
    gid = groups.get_system("ssl-cert").gid

    if webroot:
        webroot = os.path.join(webroot, ".well-known", "acme-challenge")

    acme_dir = config.get("certificates", "acme_dir")
    cert_dir = os.path.join(acme_dir, "certs", domain)
    cert_path = os.path.join(cert_dir, "cert.pem")
    key_path = os.path.join(cert_dir, "privkey.pem")

    if not os.path.exists(cert_dir):
        os.makedirs(cert_dir)

    if not webroot:
        sites = websites.get()
        for x in sites:
            if x.port in [80, 443] and x.domain == domain:
                webroot = x.add_acme_challenge()
                break
        else:
            webroot = websites.create_acme_dummy(domain)

    smsg = "Requesting certificate from Let's Encrypt CA..."
    nthread.update(Notification("info", "Certificates", smsg))
    agree_to_tos = None
    has_written_files = False
    while True:
        try:
            leclient.issue_certificate(
                domains,
                acme_dir,
                acme_server=config.get("certificates", "acme_server"),
                certificate_file=cert_path,
                private_key_file=key_path,
                agree_to_tos_url=agree_to_tos)
            break
        except leclient.NeedToAgreeToTOS as e:
            agree_to_tos = e.url
            continue
        except leclient.NeedToTakeAction as e:
            if not has_written_files:
                if not os.path.exists(webroot):
                    os.makedirs(webroot)
                os.chown(webroot, uid, gid)
                for x in e.actions:
                    fn = os.path.join(webroot, x.file_name)
                    with open(fn, 'w') as f:
                        f.write(x.contents)
                    os.chown(fn, uid, gid)
                has_written_files = True
                continue
            else:
                raise errors.InvalidConfigError(
                    "Requesting a certificate failed - it doesn't appear your "
                    "requested domain's DNS is pointing to your server, or "
                    "there was a port problem. Please check these things and "
                    "try again.")
        except leclient.WaitABit as e:
            while e.until_when > datetime.datetime.now():
                until = e.until_when - datetime.datetime.now()
                until_secs = int(round(until.total_seconds())) + 1
                if until_secs > 300:
                    raise errors.InvalidConfigError(
                        "Requesting a certificate failed - LE rate limiting "
                        "detected, for a period of more than five minutes. "
                        "Please try again later."
                    )
                nthread.update(
                    Notification(
                        "warning", "Certificates", "LE rate limiting detected."
                        " Will reattempt in {0} seconds".format(until_secs))
                    )
                time.sleep(until_secs)
            continue
        except leclient.InvalidDomainName:
            raise errors.InvalidConfigError(
                "Requesting a certificate failed - invalid domain name"
            )
        except leclient.RateLimited:
            raise errors.InvalidConfigError(
                "Requesting a certificate failed - LE is refusing to issue "
                "more certificates to you for this domain. Please choose "
                "another domain or try again another time."
            )

    os.chown(cert_path, -1, gid)
    os.chown(key_path, -1, gid)
    os.chmod(cert_path, 0o750)
    os.chmod(key_path, 0o750)

    with open(cert_path, "rb") as f:
        cert = x509.load_pem_x509_certificate(f.read(), default_backend())
    with open(key_path, "rb") as f:
        key = serialization.load_pem_private_key(
            f.read(), password=None, backend=default_backend()
        )
    sha1 = binascii.hexlify(cert.fingerprint(hashes.SHA1())).decode()
    md5 = binascii.hexlify(cert.fingerprint(hashes.MD5())).decode()
    sha1 = ":".join([sha1[i:i+2].upper() for i in range(0, len(sha1), 2)])
    md5 = ":".join([md5[i:i+2].upper() for i in range(0, len(md5), 2)])
    if isinstance(key.public_key(), rsa.RSAPublicKey):
        ktype = "RSA"
    elif isinstance(key.public_key(), dsa.DSAPublicKey):
        ktype = "DSA"
    elif isinstance(key.public_key(), ec.EllipticCurvePublicKey):
        ktype = "EC"
    else:
        ktype = "Unknown"
    ksize = key.key_size
    c = Certificate(domain, domain, cert_path, key_path, ktype, ksize,
                    [], cert.not_valid_after, sha1, md5, is_acme=True)
    storage.certificates[c.id] = c

    with open("/etc/cron.d/arkos-acme-renew", "a") as f:
        f.write("0 4 * * * systemctl reload nginx\n")
        fln = ("30 3 * * * free_tls_certificate {0} {1} {2} {3} {4} "
               ">> /var/log/acme-renew.log\n")
        f.write(fln.format(
            " ".join(domains), key_path, cert_path,
            webroot.split("/.well-known/acme-challenge")[0], acme_dir
        ))

    signals.emit("certificates", "post_add", c)
    msg = "Certificate issued successfully"
    nthread.complete(Notification("success", "Certificates", msg))
    return c
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite'

        username = vars.get("wb-username")
        passwd = vars.get("wb-passwd") + username + secret_key
        passwd = hashlib.sha1(passwd).hexdigest()

        # Write a standard Wallabag config file
        shutil.copy(os.path.join(self.path, 'inc/poche/config.inc.default.php'),
            os.path.join(self.path, 'inc/poche/config.inc.php'))
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'r') as f:
            ic = f.readlines()
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = '@define (\'SALT\', \''+secret_key+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = '@define (\'STORAGE\', \''+dbengine+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite':
                l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/'+self.db.id+'.db\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_DB\', \''+self.db.id+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_USER\', \''+self.db.id+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_PASSWORD\', \''+dbpasswd+'\');\n'
                oc.append(l)
            else:
                oc.append(l)
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'w') as f:
            f.writelines(oc)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3', 
            'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite', 
            'zip', 'tidy', 'xcache', 'openssl')

        # Set up Composer and install the proper modules
        php.composer_install(self.path)
        
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'mysql':
            with open(os.path.join(self.path, 'install/mysql.sql')) as f:
                self.db.execute(f.read())
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username),
                commit=True)
            lid = int(self.db.manager.connection.insert_id())
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');" % lid,
                commit=True)
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');" % lid,
                commit=True)
        else:
            shutil.copy(os.path.join(self.path, 'install/poche.sqlite'), '/var/lib/sqlite3/%s.db' % self.db.id)
            php.open_basedir('add', '/var/lib/sqlite3')
            os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid)
            os.chmod("/var/lib/sqlite3/%s.db", 0664)
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username))
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');")
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');")
        shutil.rmtree(os.path.join(self.path, 'install'))

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        for r, d, f in os.walk(self.path):
            for x in d:
                if d in ["assets", "cache", "db"]:
                    os.chmod(os.path.join(r, d), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #40
0
            # Format extraction command according to type
            message.update("info", "Extracting source...", head="Installing website")
            if ending in [".tar.gz", ".tgz", ".tar.bz2"]:
                extract_cmd = "tar "
                extract_cmd += "xzf" if ending in [".tar.gz", ".tgz"] else "xjf"
                extract_cmd += " /tmp/%s -C %s --strip 1" % (self.id+ending, self.path)
            else:
                extract_cmd = "unzip -d %s /tmp/%s" % (self.path, self.id+ending)
            status = shell(extract_cmd)
            if status["code"] >= 1:
                raise Exception(status["stderr"])
            os.remove(pkg_path)

        # Set proper starting permissions on source directory
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0644)
                os.chown(os.path.join(r, x), uid, gid)

        # If there is a custom path for the data directory, set it up
        if hasattr(self.meta, "website_datapaths") and self.meta.website_datapaths \
                and extra_vars.get("datadir"):
            self.data_path = extra_vars["datadir"]
            if not os.path.exists(self.data_path):
                os.makedirs(self.data_path)
            os.chmod(self.data_path, 0755)
Example #41
0
    def _install(self, extra_vars, enable, nthread):
        nthread.title = "Installing website"

        msg = Notification("info", "Webs", "Preparing to install...")
        nthread.update(msg)

        # Make sure the chosen port is indeed open
        if not tracked_services.is_open_port(self.port, self.domain):
            cname = "({0})".format(self.app.id)
            raise errors.InvalidConfigError(cname, nthread)\
                from tracked_services.PortConflictError(self.port, self.domain)

        # Set some metadata values
        specialmsg, dbpasswd = "", ""
        site_dir = config.get("websites", "site_dir")
        path = (self.path or os.path.join(site_dir, self.id))
        self.path = path
        self.php = extra_vars.get("php") or self.php \
            or self.app.uses_php or False
        self.version = self.app.version.rsplit("-", 1)[0] \
            if self.app.website_updates else None

        # Classify the source package type
        if not self.app.download_url:
            ending = ""
        elif self.app.download_url.endswith(".tar.gz"):
            ending = ".tar.gz"
        elif self.app.download_url.endswith(".tgz"):
            ending = ".tgz"
        elif self.app.download_url.endswith(".tar.bz2"):
            ending = ".tar.bz2"
        elif self.app.download_url.endswith(".zip"):
            ending = ".zip"
        elif self.app.download_url.endswith(".git"):
            ending = ".git"
        else:
            raise errors.InvalidConfigError(
                "Invalid source archive format in {0}".format(self.app.id))

        msg = "Running pre-installation..."
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        nthread.update(Notification("info", "Webs", msg))

        # Call website type's pre-install hook
        self.pre_install(extra_vars)

        # If needs DB and user didn't select an engine, choose one for them
        if len(self.app.database_engines) > 1 \
                and extra_vars.get("dbengine", None):
            self.app.selected_dbengine = extra_vars.get("dbengine")
        if not getattr(self.app, "selected_dbengine", None)\
                and self.app.database_engines:
            self.app.selected_dbengine = self.app.database_engines[0]

        # Create DB and/or DB user as necessary
        if getattr(self.app, "selected_dbengine", None):
            msg = "Creating database..."
            nthread.update(Notification("info", "Webs", msg))
            mgr = databases.get_managers(self.app.selected_dbengine)
            if not mgr:
                estr = "No manager found for {0}"
                raise errors.InvalidConfigError(
                    estr.format(self.app.selected_dbengine))
            # Make sure DB daemon is running if it has one
            if not mgr.state:
                svc = services.get(mgr.meta.database_service)
                svc.restart()
            self.db = mgr.add_db(self.id)
            if hasattr(self.db, "path"):
                os.chmod(self.db.path, 0o660)
                os.chown(self.db.path, -1, gid)
            # If multiuser DB type, create user
            if mgr.meta.database_multiuser:
                dbpasswd = random_string(16)
                db_user = mgr.add_user(self.id, dbpasswd)
                db_user.chperm("grant", self.db)

        # Make sure the target directory exists, but is empty
        pkg_path = os.path.join("/tmp", self.id + ending)
        if os.path.isdir(self.path):
            shutil.rmtree(self.path)
        os.makedirs(self.path)

        # Download and extract the source repo / package
        msg = "Downloading website source..."
        nthread.update(Notification("info", "Webs", msg))
        if self.app.download_url and ending == ".git":
            g = git.Repo.clone_from(self.app.download_url, self.path)
            if hasattr(self.app, "download_at_tag"):
                g = git.Git(self.path)
                g.checkout(self.app.download_git_tag)
        elif self.app.download_url:
            download(self.app.download_url, file=pkg_path, crit=True)

            # Format extraction command according to type
            msg = "Extracting source..."
            nthread.update(Notification("info", "Webs", msg))
            if ending in [".tar.gz", ".tgz", ".tar.bz2"]:
                arch = tarfile.open(pkg_path, "r:gz")
                r = (x for x in arch.getnames() if re.match("^[^/]*$", x))
                toplvl = next(r, None)
                if not toplvl:
                    raise errors.OperationFailedError(
                        "Malformed source archive")
                arch.extractall(site_dir)
                os.rename(os.path.join(site_dir, toplvl), self.path)
            else:
                arch = zipfile.ZipFile(pkg_path)
                r = (x for x in arch.namelist() if re.match("^[^/]*/$", x))
                toplvl = next(r, None)
                if not toplvl:
                    raise errors.OperationFailedError(
                        "Malformed source archive")
                arch.extractall(site_dir)
                os.rename(os.path.join(site_dir, toplvl.rstrip("/")),
                          self.path)
            os.remove(pkg_path)

        # Set proper starting permissions on source directory
        os.chmod(self.path, 0o755)
        os.chown(self.path, uid, gid)
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)

        # If there is a custom path for the data directory, set it up
        if getattr(self.app, "website_datapaths", None) \
                and extra_vars.get("datadir"):
            self.data_path = extra_vars["datadir"]
            if not os.path.exists(self.data_path):
                os.makedirs(self.data_path)
            os.chmod(self.data_path, 0o755)
            os.chown(self.data_path, uid, gid)
        elif hasattr(self, "website_default_data_subdir"):
            self.data_path = os.path.join(self.path,
                                          self.website_default_data_subdir)
        else:
            self.data_path = self.path

        # Create the nginx serverblock
        addtoblock = self.addtoblock or []
        if extra_vars.get("addtoblock"):
            addtoblock += nginx.loads(extra_vars.get("addtoblock"), False)
        default_index = "index." + ("php" if self.php else "html")
        if hasattr(self.app, "website_root"):
            webroot = os.path.join(self.path, self.app.website_root)
        else:
            webroot = self.path
        block = nginx.Conf()
        server = nginx.Server(
            nginx.Key("listen", str(self.port)),
            nginx.Key("listen", "[::]:" + str(self.port)),
            nginx.Key("server_name", self.domain), nginx.Key("root", webroot),
            nginx.Key(
                "index",
                getattr(self.app, "website_index", None) or default_index),
            nginx.Location("/.well-known/acme-challenge/",
                           nginx.Key("root", self.path)))
        if addtoblock:
            server.add(*[x for x in addtoblock])
        block.add(server)
        nginx.dumpf(block, os.path.join("/etc/nginx/sites-available", self.id))
        challenge_dir = os.path.join(self.path, ".well-known/acme-challenge/")
        if not os.path.exists(challenge_dir):
            os.makedirs(challenge_dir)

        # Create arkOS metadata file
        meta = configparser.SafeConfigParser()
        meta.add_section("website")
        meta.set("website", "id", self.id)
        meta.set("website", "app", self.app.id)
        meta.set("website", "ssl",
                 self.cert.id if getattr(self, "cert", None) else "None")
        meta.set("website", "version", self.version or "None")
        if getattr(self.app, "website_datapaths", None) \
                and self.data_path:
            meta.set("website", "data_path", self.data_path)
        meta.set("website", "dbengine", "")
        meta.set("website", "dbengine",
                 getattr(self.app, "selected_dbengine", ""))
        with open(os.path.join(self.path, ".arkos"), "w") as f:
            meta.write(f)

        # Call site type's post-installation hook
        msg = "Running post-installation. This may take a few minutes..."
        nthread.update(Notification("info", "Webs", msg))
        specialmsg = self.post_install(extra_vars, dbpasswd)

        # Cleanup and reload daemons
        msg = "Finishing..."
        nthread.update(Notification("info", "Webs", msg))
        self.installed = True
        storage.websites[self.id] = self
        if self.port == 80:
            cleanup_acme_dummy(self.domain)
        signals.emit("websites", "site_installed", self)
        if enable:
            self.nginx_enable()
        if enable and self.php:
            php.open_basedir("add", "/srv/http/")
            php_reload()

        msg = "{0} site installed successfully".format(self.app.name)
        nthread.complete(Notification("success", "Webs", msg))
        if specialmsg:
            return specialmsg
Example #42
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite'

        username = vars.get("wb-username")
        passwd = vars.get("wb-passwd") + username + secret_key
        passwd = hashlib.sha1(passwd).hexdigest()

        # Write a standard Wallabag config file
        shutil.copy(
            os.path.join(self.path, 'inc/poche/config.inc.default.php'),
            os.path.join(self.path, 'inc/poche/config.inc.php'))
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'),
                  'r') as f:
            ic = f.readlines()
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = '@define (\'SALT\', \'' + secret_key + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = '@define (\'STORAGE\', \'' + dbengine + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite':
                l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/' + self.db.id + '.db\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_DB\', \'' + self.db.id + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_USER\', \'' + self.db.id + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_PASSWORD\', \'' + dbpasswd + '\');\n'
                oc.append(l)
            else:
                oc.append(l)
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'),
                  'w') as f:
            f.writelines(oc)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3',
                       'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                       'zip', 'tidy', 'xcache', 'openssl')

        # Set up Composer and install the proper modules
        php.composer_install(self.path)

        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'mysql':
            with open(os.path.join(self.path, 'install/mysql.sql')) as f:
                self.db.execute(f.read())
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');"
                % (username, passwd, username),
                commit=True)
            lid = int(self.db.manager.connection.insert_id())
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');"
                % lid,
                commit=True)
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');"
                % lid,
                commit=True)
        else:
            shutil.copy(os.path.join(self.path, 'install/poche.sqlite'),
                        '/var/lib/sqlite3/%s.db' % self.db.id)
            php.open_basedir('add', '/var/lib/sqlite3')
            os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid)
            os.chmod("/var/lib/sqlite3/%s.db", 0664)
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');"
                % (username, passwd, username))
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');"
            )
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');"
            )
        shutil.rmtree(os.path.join(self.path, 'install'))

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        for r, d, f in os.walk(self.path):
            for x in d:
                if d in ["assets", "cache", "db"]:
                    os.chmod(os.path.join(r, d), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #43
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        if not self.data_path.startswith(self.path):
            os.makedirs(os.path.join(self.path, "data"))
            os.chown(os.path.join(self.path, "data"), uid, gid)
            php.open_basedir('add', self.data_path)

        # Create ownCloud automatic configuration file
        with open(os.path.join(self.path, 'config', 'autoconfig.php'),
                  'w') as f:
            f.write('<?php\n'
                    '   $AUTOCONFIG = array(\n'
                    '   "adminlogin" => "admin",\n'
                    '   "adminpass" => "' + dbpasswd + '",\n'
                    '   "dbtype" => "mysql",\n'
                    '   "dbname" => "' + self.db.id + '",\n'
                    '   "dbuser" => "' + self.db.id + '",\n'
                    '   "dbpass" => "' + dbpasswd + '",\n'
                    '   "dbhost" => "localhost",\n'
                    '   "dbtableprefix" => "",\n'
                    '   "directory" => "' + self.data_path + '",\n'
                    '   );\n'
                    '?>\n')
        os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap', 'iconv',
                       'openssl', 'xcache', 'posix')

        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        with open('/etc/php/conf.d/xcache.ini', 'w') as f:
            f.writelines([
                'extension=xcache.so\n', 'xcache.size=64M\n',
                'xcache.var_size=64M\n', 'xcache.admin.enable_auth = Off\n',
                'xcache.admin.user = "******"\n',
                'xcache.admin.pass = "******"\n'
            ])

        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell("sudo -u http php index.php")
        if s["code"] != 0:
            raise Exception("ownCloud database population failed")
        s = shell("sudo -u http php occ app:enable user_ldap")
        if s["code"] != 0:
            raise Exception("ownCloud LDAP configuration failed")
        os.chdir(mydir)

        ldap_sql = (
            "REPLACE INTO appconfig (appid, configkey, configvalue) VALUES"
            "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
            "('user_ldap', 'ldap_host', 'localhost'),"
            "('user_ldap', 'ldap_port', '389'),"
            "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_tls', '0'),"
            "('user_ldap', 'ldap_display_name', 'cn'),"
            "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount'),"
            "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup'),"
            "('user_ldap', 'ldap_group_display_name', 'cn'),"
            "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'),"
            "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
            "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
            "('user_ldap', 'ldap_quota_def', ''),"
            "('user_ldap', 'ldap_email_attr', 'mail'),"
            "('user_ldap', 'ldap_cache_ttl', '600'),"
            "('user_ldap', 'ldap_configuration_active', '1'),"
            "('user_ldap', 'home_folder_naming_rule', ''),"
            "('user_ldap', 'ldap_backup_host', ''),"
            "('user_ldap', 'ldap_dn', ''),"
            "('user_ldap', 'ldap_agent_password', ''),"
            "('user_ldap', 'ldap_backup_port', ''),"
            "('user_ldap', 'ldap_nocase', ''),"
            "('user_ldap', 'ldap_turn_off_cert_check', ''),"
            "('user_ldap', 'ldap_override_main_server', ''),"
            "('user_ldap', 'ldap_attributes_for_user_search', ''),"
            "('user_ldap', 'ldap_attributes_for_group_search', ''),"
            "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
            "('user_ldap', 'ldap_expert_uuid_attr', '');")
        self.db.execute(ldap_sql, commit=True)
        # TODO set authed user name
        self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');",
                        commit=True)
    def post_install(self, vars, dbpasswd=""):
        with open(os.path.join(self.path, 'package.json'), 'r') as f:
            d = json.loads(f.read())
        del d['dependencies']['bcryptjs']
        d['dependencies']['bcrypt'] = '0.8.1'
        with open(os.path.join(self.path, 'package.json'), 'w') as f:
            f.write(json.dumps(d))
        with open(os.path.join(self.path, 'core/server/models/user.js'), 'r') as f:
            d = f.read()
        d = d.replace('bcryptjs', 'bcrypt')
        with open(os.path.join(self.path, 'core/server/models/user.js'), 'w') as f:
            f.write(d)
        if os.path.exists(os.path.join(self.path, 'npm-shrinkwrap.json')):
            os.unlink(os.path.join(self.path, 'npm-shrinkwrap.json'))

        nodejs.install_from_package(self.path, 'production', {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'})
        users.SystemUser("ghost").add()

        # Get Mail settings
        mail_settings = {
            'transport' : vars.get('ghost-transport') or "",
            'service' : vars.get('ghost-service') or "",
            'mail_user' : vars.get('ghost-mail-user') or "",
            'mail_pass' : vars.get('ghost-mail-pass') or "",
            'from_address' : vars.get('ghost-from-address') or ""
        }

        # Create/Edit the Ghost config file
        with open(os.path.join(self.path, 'config.example.js'), 'r') as f:
            data = f.read()
        data = data.replace("port: '2368'", "port: '%s'" % self.backend_port)
        data = data.replace('http://my-ghost-blog.com', 'http://'+self.addr+(':'+str(self.port) if str(self.port) != '80' else''))
        if len(set(mail_settings.values())) != 1 and\
           mail_settings['transport'] != '':
            # If the mail settings exist, add them
            data = data.replace(
                "mail: {},",\
                'mail: {\n'
                "\tfromaddress: '" + mail_settings['from_address'] + "',\n"
                "\ttransport: '" + mail_settings['transport'] + "',\n"
                "\t\toptions: {\n"
                "\t\t\tservice: '" + mail_settings['service'] + "',\n"
                "\t\t\tauth: {\n"
                "\t\t\t\tuser: '******'mail_user'] + "',\n"
                "\t\t\t\tpass: '******'mail_pass'] + "'\n"
                "\t\t\t}\n"
                "\t\t}\n"
                "},\n"
            )
        with open(os.path.join(self.path, 'config.js'), 'w') as f:
            f.write(data)

        # Finally, make sure that permissions are set so that Ghost
        # can make adjustments and save plugins when need be.
        uid = users.get_system("ghost").uid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, -1)
            for x in f:
                os.chown(os.path.join(r, x), uid, -1)
        
        cfg = {
                'directory': self.path,
                'user': '******',
                'command': 'node %s'%os.path.join(self.path, 'index.js'),
                'autostart': 'true',
                'autorestart': 'true',
                'environment': 'NODE_ENV="production"',
                'stdout_logfile': '/var/log/ghost.log',
                'stderr_logfile': '/var/log/ghost.log'
            }
        s = services.Service(self.id, "supervisor", cfg=cfg)
        s.add()
Example #45
0
    def post_install(self, extra_vars, dbpasswd=""):
        with open(os.path.join(self.path, 'package.json'), 'r') as f:
            d = json.loads(f.read())
        del d['dependencies']['bcryptjs']
        d['dependencies']['bcrypt'] = '0.8.5'
        d['engines']['node'] = '~0.10.0 || ~0.12.0 || ^4.2.0 || ^5.6.0'
        with open(os.path.join(self.path, 'package.json'), 'w') as f:
            f.write(json.dumps(d))
        with open(os.path.join(self.path, 'core/server/models/user.js'),
                  'r') as f:
            d = f.read()
        d = d.replace('bcryptjs', 'bcrypt')
        with open(os.path.join(self.path, 'core/server/models/user.js'),
                  'w') as f:
            f.write(d)
        if os.path.exists(os.path.join(self.path, 'npm-shrinkwrap.json')):
            os.unlink(os.path.join(self.path, 'npm-shrinkwrap.json'))

        nodejs.install_from_package(self.path, 'production',
                                    {'python': '/usr/bin/python2'})
        users.SystemUser("ghost").add()

        # Get Mail settings
        mail_settings = {
            'transport': extra_vars.get('gh-transport') or "",
            'service': extra_vars.get('gh-service') or "",
            'mail_user': extra_vars.get('gh-mail-user') or "",
            'mail_pass': extra_vars.get('gh-mail-pass') or "",
            'from_address': extra_vars.get('gh-from-address') or ""
        }

        # Create/Edit the Ghost config file
        with open(os.path.join(self.path, 'config.example.js'), 'r') as f:
            data = f.read()
        data = data.replace("port: '2368'",
                            "port: '{0}'".format(self.backend_port))
        data = data.replace(
            'http://my-ghost-blog.com', 'http://{0}' +
            (':' + str(self.port) if str(self.port) != '80' else '').format(
                self.addr))
        if len(set(mail_settings.values())) != 1 and\
           mail_settings['transport'] != '':
            # If the mail settings exist, add them
            data = data.replace(
                "mail: {},", 'mail: {\n'
                "\tfromaddress: '" + mail_settings['from_address'] + "',\n"
                "\ttransport: '" + mail_settings['transport'] + "',\n"
                "\t\toptions: {\n"
                "\t\t\tservice: '" + mail_settings['service'] + "',\n"
                "\t\t\tauth: {\n"
                "\t\t\t\tuser: '******'mail_user'] + "',\n"
                "\t\t\t\tpass: '******'mail_pass'] + "'\n"
                "\t\t\t}\n"
                "\t\t}\n"
                "},\n")
        with open(os.path.join(self.path, 'config.js'), 'w') as f:
            f.write(data)

        # Finally, make sure that permissions are set so that Ghost
        # can make adjustments and save plugins when need be.
        uid = users.get_system("ghost").uid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, -1)
            for x in f:
                os.chown(os.path.join(r, x), uid, -1)

        cfg = {
            'directory': self.path,
            'user': '******',
            'command': 'node {0}'.format(os.path.join(self.path, 'index.js')),
            'autostart': 'true',
            'autorestart': 'true',
            'environment': 'NODE_ENV="production"',
            'stdout_logfile': '/var/log/ghost.log',
            'stderr_logfile': '/var/log/ghost.log'
        }
        s = services.Service(self.id, "supervisor", cfg=cfg)
        s.add()