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)
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)
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)
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)
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)
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)
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)
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'))
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 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)
def chkpath(self): # Make sure the db dir exists and that it has the right perms g = groups.get_system("sqlite3") if not g: g = groups.SystemGroup("sqlite3", users=["http"]) g.add() if not os.path.isdir('/var/lib/sqlite3'): os.makedirs('/var/lib/sqlite3') if oct(stat.S_IMODE(os.stat('/var/lib/sqlite3').st_mode)) != 0775: os.chmod('/var/lib/sqlite3', 0775) if int(os.stat('/var/lib/sqlite3').st_gid) != g.gid: os.chown('/var/lib/sqlite3', -1, g.gid)
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'))
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)
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)
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)
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)
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)
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)
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)
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=""): # 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.'
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)
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() 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)
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)
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
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
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import dsa, rsa, ec import datetime from free_tls_certificates import client as leclient import glob import os import time from arkos import config, signals, storage, websites, applications, logger from arkos.messages import Notification, NotificationThread from arkos.system import users, groups from arkos.utilities import errors, shell if not groups.get_system("ssl-cert"): groups.SystemGroup("ssl-cert").add() gid = groups.get_system("ssl-cert").gid class Certificate: """ Represents a TLS certificate managed by arkOS. Certificates can be generated (self-signed), generated from Let's Encrypt CA, or installed from external sources. When certificates are self-signed, they are accompanied by generated certificate authorities allowing client trust for the root domain in question. ``Assign`` objects that are sent to/from this class look like this:
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=""): 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)
# 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)
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()
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)