Exemplo n.º 1
0
class PHP(Plugin):
    implements(apis.langassist.ILangMgr)
    name = 'PHP'

    def install_composer(self):
        cwd = os.getcwd()
        os.environ['COMPOSER_HOME'] = '/root'
        self.enable_mod('phar')
        self.open_basedir('add', '/root')
        s = shell_cs('cd /root; curl -sS https://getcomposer.org/installer | php', stderr=True)
        if s[0] != 0:
            raise Exception('Composer download/config failed. Error: %s'%str(s[1]))
        os.rename('/root/composer.phar', '/usr/local/bin/composer')
        os.chmod('/usr/local/bin/composer', 755)
        self.open_basedir('add', '/usr/local/bin')
        shell('cd %s'%cwd)

    def verify_composer(self):
        if not shell_status('which composer') == 0:
            self.install_composer()
        if not shell_status('which composer') == 0:
            raise Exception('Composer was not installed successfully.')

    def composer_install(self, path):
        self.verify_composer()
        s = shell_cs('cd %s; composer install'%path, stderr=True)
        if s[0] != 0:
            raise Exception('Composer failed to install this app\'s bundle. Error: %s'%str(s[1]))

    def enable_mod(self, *mod):
        for x in mod:
            shell('sed -i s/\;extension=%s.so/extension=%s.so/g /etc/php/php.ini'%(x,x))

    def disable_mod(self, *mod):
        for x in mod:
            shell('sed -i s/extension=%s.so/\;extension=%s.so/g /etc/php/php.ini'%(x,x))

    def open_basedir(self, op, path):
        if op == 'add':
            ic = open('/etc/php/php.ini', 'r').readlines()
            f = open('/etc/php/php.ini', 'w')
            oc = []
            for l in ic:
                if 'open_basedir = ' in l and path not in l:
                    l = l.rstrip('\n') + ':%s\n' % path
                    oc.append(l)
                else:
                    oc.append(l)
            f.writelines(oc)
            f.close()
        elif op == 'del':
            ic = open('/etc/php/php.ini', 'r').readlines()
            f = open('/etc/php/php.ini', 'w')
            oc = []
            for l in ic:
                if 'open_basedir = ' in l and path in l:
                    l = l.replace(':'+path, '')
                    l = l.replace(':'+path+'/', '')
                    oc.append(l)
                else:
                    oc.append(l)
            f.writelines(oc)
            f.close()

    def upload_size(self, size):
        ic = open('/etc/php/php.ini', 'r').readlines()
        f = open('/etc/php/php.ini', 'w')
        oc = []
        for l in ic:
            if 'upload_max_filesize = ' in l:
                l = 'upload_max_filesize = %sM' % size
            elif 'post_max_size = ' in l:
                l = 'post_max_size = %sM' % size
            oc.append(l)
        f.writelines(oc)
        f.close()
Exemplo n.º 2
0
Arquivo: main.py Projeto: tewe/genesis
class Wallabag(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('~ /(db)', nginx.Key('deny', 'all'),
                       nginx.Key('return', '404')),
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, name, vars):
        dbname = vars.getvalue('wb-dbname', '')
        dbpasswd = vars.getvalue('wb-dbpasswd', '')
        if dbname and dbpasswd:
            apis.databases(self.app).get_interface('MariaDB').validate(
                dbname, dbname, dbpasswd)
        elif dbname:
            raise Exception(
                'You must enter a database password if you specify a database name!'
            )
        elif dbpasswd:
            raise Exception(
                'You must enter a database name if you specify a database password!'
            )

    def post_install(self, name, path, vars):
        # Get the database object, and determine proper values
        phpctl = apis.langassist(self.app).get_interface('PHP')
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        if vars.getvalue('wb-dbname', '') == '':
            dbname = name
        else:
            dbname = vars.getvalue('wb-dbname')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        if vars.getvalue('wb-dbpasswd', '') == '':
            passwd = secret_key[0:8]
        else:
            passwd = vars.getvalue('wb-dbpasswd')

        # Request a database and user to interact with it
        dbase.add(dbname, conn)
        dbase.usermod(dbname, 'add', passwd, conn)
        dbase.chperm(dbname, dbname, 'grant', conn)

        # Write a standard Wallabag config file
        shutil.copy(os.path.join(path, 'inc/poche/config.inc.php.new'),
                    os.path.join(path, 'inc/poche/config.inc.php'))
        ic = open(os.path.join(path, 'inc/poche/config.inc.php'),
                  'r').readlines()
        f = open(os.path.join(path, 'inc/poche/config.inc.php'), 'w')
        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\', \'mysql\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l:
                l = 'define (\'STORAGE_DB\', \'' + dbname + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l:
                l = 'define (\'STORAGE_USER\', \'' + dbname + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l:
                l = 'define (\'STORAGE_PASSWORD\', \'' + passwd + '\');\n'
                oc.append(l)
            else:
                oc.append(l)
        f.writelines(oc)
        f.close()

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql', 'pdo_mysql', 'zip', 'tidy', 'xcache',
                          'openssl')

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

        # Finish setting up the database then delete the install folder
        dbase.execute(dbname,
                      open(os.path.join(path, 'install/mysql.sql')).read(),
                      conn)
        shutil.rmtree(os.path.join(path, 'install'))

        # Finally, make sure that permissions are set so that Poche
        # can make adjustments and save plugins when need be.
        shell('chmod -R 755 ' + os.path.join(path, 'assets/') + ' ' +
              os.path.join(path, 'cache/') + ' ' + os.path.join(path, 'db/'))
        shell('chown -R http:http ' + path)

    def pre_remove(self, name, path):
        f = open(os.path.join(path, 'inc/poche/config.inc.php'), 'r')
        for line in f.readlines():
            if 'STORAGE_DB' in line:
                data = line.split('\'')[1::2]
                dbname = data[1]
                break
        f.close()
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        dbase.remove(dbname, conn)
        dbase.usermod(dbname, 'del', '', conn)

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass
Exemplo n.º 3
0
class WordPress(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, name, vars):
        dbname = vars.getvalue('wp-dbname', '')
        dbpasswd = vars.getvalue('wp-dbpasswd', '')
        if dbname and dbpasswd:
            apis.databases(self.app).get_interface('MariaDB').validate(
                dbname, dbname, dbpasswd)
        elif dbname:
            raise Exception(
                'You must enter a database password if you specify a database name!'
            )
        elif dbpasswd:
            raise Exception(
                'You must enter a database name if you specify a database password!'
            )

    def post_install(self, name, path, vars):
        # Get the database object, and determine proper values
        phpctl = apis.langassist(self.app).get_interface('PHP')
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        if vars.getvalue('wp-dbname', '') == '':
            dbname = name
        else:
            dbname = vars.getvalue('wp-dbname')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        if vars.getvalue('wp-dbpasswd', '') == '':
            passwd = secret_key[0:8]
        else:
            passwd = vars.getvalue('wp-dbpasswd')

        # Request a database and user to interact with it
        dbase.add(dbname, conn)
        dbase.usermod(dbname, 'add', passwd, conn)
        dbase.chperm(dbname, dbname, 'grant', conn)

        # 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
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        f.write('<?php\n'
                'define(\'DB_NAME\', \'' + dbname + '\');\n'
                'define(\'DB_USER\', \'' + dbname + '\');\n'
                'define(\'DB_PASSWORD\', \'' + passwd + '\');\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')
        f.close()

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql', 'xcache')

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        shell('chown -R http:http ' + path)

    def pre_remove(self, name, path):
        f = open(os.path.join(path, 'wp-config.php'), 'r')
        for line in f.readlines():
            if 'DB_NAME' in line:
                data = line.split('\'')[1::2]
                dbname = data[1]
                break
        f.close()
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        dbase.remove(dbname, conn)
        dbase.usermod(dbname, 'del', '', conn)

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        ic = open(os.path.join(path, 'wp-config.php'), 'r').readlines()
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            oc.append('define(\'FORCE_SSL_ADMIN\', true);\n')
        f.writelines(oc)
        f.close()

    def ssl_disable(self, path):
        ic = open(os.path.join(path, 'wp-config.php'), 'r').readlines()
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            oc.append('define(\'FORCE_SSL_ADMIN\', false);\n')
        f.writelines(oc)
        f.close()
Exemplo n.º 4
0
class WordPress(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'WordPress'
    dpath = 'https://wordpress.org/latest.tar.gz'
    icon = 'gen-earth'
    php = True
    nomulti = True

    addtoblock = ('	location = /favicon.ico {\n'
                  '		log_not_found off;\n'
                  '		access_log off;\n'
                  '	}\n'
                  '\n'
                  '	location = /robots.txt {\n'
                  '		allow all;\n'
                  '		log_not_found off;\n'
                  '		access_log off;\n'
                  '	}\n'
                  '\n'
                  '	location / {\n'
                  '		try_files $uri $uri/ /index.php?$args;\n'
                  '	}\n'
                  '\n'
                  '	location ~ \.php$ {\n'
                  '		fastcgi_pass unix:/run/php-fpm/php-fpm.sock;\n'
                  '		fastcgi_index index.php;\n'
                  '		include fastcgi.conf;\n'
                  '}\n'
                  '\n'
                  '	location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {\n'
                  '		expires max;\n'
                  '		log_not_found off;\n'
                  '	}\n')

    def pre_install(self, name, vars):
        pass

    def post_install(self, name, path, vars):
        # Get the database object, and determine proper values
        dbase = apis.databases(self.app).get_interface('MariaDB')
        if vars.getvalue('wp-dbname', '') == '':
            dbname = name
        else:
            dbname = vars.getvalue('wp-dbname')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        if vars.getvalue('wp-dbpasswd', '') == '':
            passwd = secret_key[0:8]
        else:
            passwd = vars.getvalue('wp-dbpasswd')

        # Request a database and user to interact with it
        dbase.add(dbname)
        dbase.usermod(dbname, 'add', passwd)
        dbase.chperm(dbname, dbname, 'grant')

        # Write a standard WordPress config file
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        f.write('<?php\n'
                'define(\'DB_NAME\', \'' + dbname + '\');\n'
                'define(\'DB_USER\', \'' + dbname + '\');\n'
                'define(\'DB_PASSWORD\', \'' + passwd + '\');\n'
                'define(\'DB_HOST\', \'localhost\');\n'
                'define(\'DB_CHARSET\', \'utf8\');\n'
                'define(\'SECRET_KEY\', \'' + secret_key + '\');\n'
                '\n'
                'define(\'WP_CACHE\', true);\n'
                '\n'
                '/*\n'
                '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'
                '*/'
                '\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')
        f.close()

        # Make sure that the correct PHP settings are enabled
        shell(
            'sed -i s/;extension=mysql.so/extension=mysql.so/g /etc/php/php.ini'
        )

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        shell('chown -R http:http ' + path)

    def pre_remove(self, name, path):
        f = open(os.path.join(path, 'wp-config.php'), 'r')
        for line in f.readlines():
            if 'DB_NAME' in line:
                data = line.split('\'')[1::2]
                dbname = data[1]
                break
        f.close()
        dbase = apis.databases(self.app).get_interface('MariaDB')
        dbase.remove(dbname)
        dbase.usermod(dbname, 'del', '')

    def post_remove(self, name):
        pass

    def get_info(self):
        return {
            'name':
            'WordPress',
            'short':
            'Open-source CMS and blogging platform',
            'long':
            ('WordPress started as just a blogging system, '
             'but has evolved to be used as full content management system '
             'and so much more through the thousands of plugins, widgets, '
             'and themes, WordPress is limited only by your imagination. '
             '(And tech chops.)'),
            'site':
            'http://wordpress.org',
            'logo':
            True
        }
Exemplo n.º 5
0
class Ghost(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'Ghost'
    dpath = 'https://ghost.org/zip/ghost-0.3.3.zip'
    icon = 'gen-earth'
    php = False
    nomulti = True
    ssl = False

    addtoblock = ('    location / {\n'
                  '        proxy_pass http://127.0.0.1:2368/;\n'
                  '        proxy_set_header Host $host;\n'
                  '        proxy_buffering off;\n'
                  '    }\n'
                  '\n')

    def pre_install(self, name, vars):
        port = vars.getvalue('ghost-port', '2368')
        try:
            int(port)
        except ValueError:
            raise Exception('Invalid Port: %s' % port)

    def post_install(self, name, path, vars):
        port = vars.getvalue('ghost-port', '2368')
        hostname = vars.getvalue('ghost-host', '127.0.0.1')
        url = vars.getvalue('ghost-url', 'my-ghost-blog.com')

        replacements = [('2368', port), ('127.0.0.1', hostname),
                        ('my-ghost-blog.com', url)]

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

        # Create/Edit the Ghost config file
        f = open(os.path.join(path, 'config.example.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            for r in replacements:
                f = f.replace(r[0], r[1])
            if len(set(mail_settings.values())) != 1 and\
               mail_settings['transport'] != '':
                # If the mail settings exist, add them
                f = f.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"
                )
            config_file.write(f)
            config_file.close()

        # Finally, make sure that permissions are set so that Ghost
        # can make adjustments and save plugins when need be.
        shell('chown -R http:http ' + path)

    def pre_remove(self, name, path):
        pass

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass

    def get_info(self):
        return {
            'name':
            'Ghost',
            'short':
            'Just a blogging platform.',
            'long': ("Ghost is a platform dedicated to one thing: Publishing."
                     "It's beautifully designed, completely customisable and"
                     "completely Open Source. Ghost allows you to write and"
                     "publish your own blog, giving you the tools to make it"
                     "easy and even fun to do. It's simple, elegant, and"
                     "designed so that you can spend less time messing with"
                     "making your blog work - and more time blogging."),
            'site':
            'http://ghost.org',
            'logo':
            True
        }
Exemplo n.º 6
0
Arquivo: main.py Projeto: ajvb/genesis
class Jekyll(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'Jekyll'
    dpath = 'https://uspx.arkos.io/resources/jekyll-sample.tar.gz'
    icon = 'gen-earth'
    php = False
    nomulti = False
    ssl = True

    addtoblock = ''

    def pre_install(self, name, vars):
        # Make sure Ruby directory is in the PATH.
        # This should work until there is a viable Ruby (RVM) plugin for Genesis
        profile = []
        f = open('/etc/profile', 'r')
        for l in f.readlines():
            if l.startswith('PATH="') and not 'ruby/2.0.0/bin' in l:
                l = l.rstrip('"\n')
                l += ':/root/.gem/ruby/2.0.0/bin"\n'
                profile.append(l)
                os.environ[
                    'PATH'] = os.environ['PATH'] + ':/root/.gem/ruby/2.0.0/bin'
            else:
                profile.append(l)
        f.close()
        open('/etc/profile', 'w').writelines(profile)

        # Install the Jekyll and rdiscount gems required.
        if not any('jekyll' in s for s in shell('gem list').split('\n')):
            shell('gem install --user-install jekyll')
        if not any('rdiscount' in s for s in shell('gem list').split('\n')):
            shell('gem install --user-install rdiscount')

    def post_install(self, name, path, vars):
        # Make sure the webapps config points to the _site directory and generate it.
        shell(
            'sed -i "s/.*root .*/   root %s\;/" /etc/nginx/sites-available/%s'
            % (re.escape(path + '/_site'), name))
        shell('jekyll build --source ' + path + ' --destination ' + path +
              '/_site')

        # Return an explicatory message.
        return 'Jekyll has been setup, with a sample site at ' + path + '. Modify these files as you like. To learn how to use Jekyll, visit http://jekyllrb.com/docs/usage. After making changes, click the Configure button next to the site, then "Regenerate Site" to bring your changes live.'

    def pre_remove(self, name, path):
        pass

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass

    def regenerate_site(self, site):
        shell('jekyll build --source ' + site['path'].rstrip('_site') +
              ' --destination ' + os.path.join(site['path']))

    def get_info(self):
        return {
            'name':
            'Jekyll',
            'short':
            'Transform your plain text into static websites and blogs.',
            'long': ('Jekyll is a simple, blog-aware, static site '
                     'generator. It takes a template directory containing raw '
                     'text files in various formats, runs it through Markdown '
                     '(or Textile) and Liquid converters, and spits out a '
                     'complete, ready-to-publish static website suitable for '
                     'serving with your favorite web server.'),
            'site':
            'http://jekyllrb.com',
            'logo':
            True
        }
Exemplo n.º 7
0
class Etherpad(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'Etherpad'
    icon = 'gen-pen'

    addtoblock = [
        nginx.Location('/', nginx.Key('proxy_pass', 'http://127.0.0.1:2369'),
                       nginx.Key('proxy_set_header', 'X-Real-IP $remote_addr'),
                       nginx.Key('proxy_set_header', 'Host $host'),
                       nginx.Key('proxy_buffering', 'off'))
    ]

    def pre_install(self, name, vars):
        eth_name = vars.getvalue('ether_admin', '')
        eth_pass = vars.getvalue('ether_pass', '')
        if not (eth_name and eth_pass):
            raise Exception('You must enter an admin name AND password'
                            'in the App Settings tab!')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        apis.databases(self.app).get_interface('MariaDB').validate(
            name, name, eth_pass, conn)

    def post_install(self, name, path, vars, dbinfo={}):
        UsersBackend(self.app).add_user('etherpad')

        # Create/Edit the config file
        cfg = {
            "title":
            "Etherpad",
            "favicon":
            "favicon.ico",
            "ip":
            "127.0.0.1",
            "port":
            "2369",
            "sessionKey":
            hashlib.sha1(str(random.random())).hexdigest(),
            "dbType":
            "mysql",
            "dbSettings": {
                "user": dbinfo['user'],
                "host": "localhost",
                "password": dbinfo['passwd'],
                "database": dbinfo['name']
            },
            "defaultPadText":
            ("Welcome to Etherpad on arkOS!\n\nThis pad text is "
             "synchronized as you type, so that everyone viewing this page "
             "sees the same text. This allows you to collaborate seamlessly "
             "on documents!\n\nGet involved with Etherpad at "
             "http://etherpad.org, or with arkOS at http://arkos.io\n"),
            "requireSession":
            False,
            "editOnly":
            False,
            "minify":
            True,
            "maxAge":
            60 * 60 * 6,
            "abiword":
            None,
            "requireAuthentication":
            False,
            "requireAuthorization":
            False,
            "trustProxy":
            True,
            "disableIPlogging":
            False,
            "socketTransportProtocols":
            ["xhr-polling", "jsonp-polling", "htmlfile"],
            "loglevel":
            "INFO",
            "logconfig": {
                "appenders": [{
                    "type": "console"
                }]
            },
            "users": {
                vars.getvalue('ether_admin'): {
                    "password": vars.getvalue('ether_pass'),
                    "is_admin": True
                },
            },
        }
        with open(os.path.join(path, 'settings.json'), 'w') as f:
            json.dump(cfg, f, indent=4)

        # node-gyp needs the HOME variable to be set
        with open(os.path.join(path, 'bin/run.sh')) as f:
            run_script = f.readlines()
        run_script.insert(1, "export HOME=%s" % path)
        with open(os.path.join(path, 'bin/run.sh'), 'w') as f:
            f.writelines(run_script)

        # Install deps right away
        if not shell(os.path.join(path, 'bin/installDeps.sh') + ' || exit 1'):
            raise RuntimeError("Etherpad dependencies could not be installed.")

        # Install selected plugins
        mods = list(  # e.g. "ep_plugin/ep_adminpads"
            str(var).split("/")[1]  #                 ^^^^^^^^^^^^
            for var in vars
            if var.startswith('ep_plugin/') and int(vars.getvalue(var)))
        if mods:
            mod_inst_path = os.path.join(path, "node_modules")
            if not os.path.exists(mod_inst_path):
                os.mkdir(mod_inst_path)
            nodectl = apis.langassist(self.app).get_interface('NodeJS')
            nodectl.install(*mods, install_path=mod_inst_path)

        # Make supervisor entry
        s = self.app.get_backend(apis.services.IServiceManager)
        s.edit(
            'etherpad', {
                'stype': 'program',
                'directory': path,
                'user': '******',
                'command': os.path.join(path, 'bin/run.sh'),
                'autostart': 'true',
                'autorestart': 'true',
                'stdout_logfile': '/var/log/etherpad.log',
                'stderr_logfile': '/var/log/etherpad.log'
            })
        s.enable('etherpad', 'supervisor')

        # Change owner of everything in the etherpad path
        shell('chown -R etherpad ' + path)
        #TODO: user auth with nginx??

    def pre_remove(self, site):
        pass

    def post_remove(self, site):
        UsersBackend(self.app).del_user('etherpad')
        self.app.get_backend(apis.services.IServiceManager).delete(
            'etherpad', 'supervisor')

    def ssl_enable(self, path, cfile, kfile):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                self.addtoblock[0].add(
                    nginx.Key('proxy_set_header',
                              'X-Forwarded-For $proxy_add_x_forwarded_for'),
                    nginx.Key('proxy_set_header', 'X-Forwarded-Proto $scheme'),
                )
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)

    def ssl_disable(self, path):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)
Exemplo n.º 8
0
class Ghost(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'Ghost'
    icon = 'gen-earth'

    addtoblock = [
        nginx.Location('/',
            nginx.Key('proxy_pass', 'http://127.0.0.1:2368'),
            nginx.Key('proxy_set_header', 'X-Real-IP $remote_addr'),
            nginx.Key('proxy_set_header', 'Host $host'),
            nginx.Key('proxy_buffering', 'off')
            )
        ]

    def pre_install(self, name, vars):
        pass

    def post_install(self, name, path, vars):
        nodectl = apis.langassist(self.app).get_interface('NodeJS')
        users = UsersBackend(self.app)

        if not os.path.exists('/usr/bin/python') and os.path.exists('/usr/bin/python'):
            os.symlink('/usr/bin/python2', '/usr/bin/python')

        # A bug in 0.4.1 prevents [email protected] from installing properly.
        # Fallback to 2.1.15
        d = json.loads(open(os.path.join(path, 'package.json'), 'r').read())
        d['dependencies']['sqlite3'] = '2.1.15'
        open(os.path.join(path, 'package.json'), 'w').write(json.dumps(d))

        nodectl.install_from_package(path, 'production')
        users.add_user('ghost')

        s = apis.orders(self.app).get_interface('supervisor')
        if s:
            s[0].order('new', 'ghost', 'program', 
                [('directory', path), ('user', 'ghost'), 
                ('command', 'node %s'%os.path.join(path, 'index.js')),
                ('autostart', 'true'), ('autorestart', 'true'),
                ('environment', 'NODE_ENV="production"'),
                ('stdout_logfile', '/var/log/ghost.log'),
                ('stderr_logfile', '/var/log/ghost.log')])

        addr = vars.getvalue('addr', 'localhost')
        port = vars.getvalue('port', '80')

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

        # Create/Edit the Ghost config file
        f = open(os.path.join(path, 'config.example.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            f = f.replace('http://my-ghost-blog.com', 'http://'+addr+(':'+port if port != '80' else''))
            if len(set(mail_settings.values())) != 1 and\
               mail_settings['transport'] != '':
                # If the mail settings exist, add them
                f = f.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"
                )
            config_file.write(f)
            config_file.close()

        # Finally, make sure that permissions are set so that Ghost
        # can make adjustments and save plugins when need be.
        shell('chown -R ghost ' + path)

    def pre_remove(self, name, path):
        pass

    def post_remove(self, name):
        users = UsersBackend(self.app)
        users.del_user('ghost')
        s = apis.orders(self.app).get_interface('supervisor')
        if s:
            s[0].order('del', 'ghost')

    def ssl_enable(self, path, cfile, kfile):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s'%name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                self.addtoblock[0].add(
                    nginx.Key('proxy_set_header', 'X-Forwarded-For $proxy_add_x_forwarded_for'),
                    nginx.Key('proxy_set_header', 'X-Forwarded-Proto $scheme'),
                )
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s'%name)
        f = open(os.path.join(path, 'config.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            f = f.replace('production: {\n        url: \'http://', 
                'production: {\n        url: \'https://')
            config_file.write(f)
            config_file.close()
        s = apis.orders(self.app).get_interface('supervisor')
        if s:
            s[0].order('rel', 'ghost')

    def ssl_disable(self, path):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s'%name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s'%name)
        f = open(os.path.join(path, 'config.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            f = f.replace('production: {\n        url: \'https://', 
                'production: {\n        url: \'http://')
            config_file.write(f)
            config_file.close()
        s = apis.orders(self.app).get_interface('supervisor')
        if s:
            s[0].order('rel', 'ghost')
Exemplo n.º 9
0
class MariaDB(Plugin):
    implements(apis.databases.IDatabase)
    name = 'MariaDB'
    icon = 'gen-database'
    task = 'mysqld'
    multiuser = True

    def add(self, dbname):
        if ' ' in dbname or '-' in dbname:
            raise Exception('Database name must not contain spaces or dashes')
        elif len(dbname) > 16:
            raise Exception('Database name must be shorter than 16 characters')
        status = shell_cs('mysql -e "CREATE DATABASE %s;"' % dbname,
                          stderr=True)
        if status[0] >= 1:
            raise Exception(status[1])

    def remove(self, dbname):
        status = shell_cs('mysql -e "DROP DATABASE %s;"' % dbname, stderr=True)
        if status[0] >= 1:
            raise Exception(status[1])

    def usermod(self, user, action, passwd):
        if action == 'add':
            status = shell_cs(
                'mysql -e "CREATE USER \'%s\'@\'localhost\' IDENTIFIED BY \'%s\';"'
                % (user, passwd),
                stderr=True)
        elif action == 'del':
            status = shell_cs('mysql -e "DROP USER \'%s\'@\'localhost\';"' %
                              user,
                              stderr=True)
        if status[0] >= 1:
            raise Exception(status[1])

    def chperm(self, dbname, user, action):
        if action == 'check':
            out = shell_cs('mysql -e "SHOW GRANTS FOR \'%s\'@\'localhost\';"' %
                           user,
                           stderr=True)
            parse = []
            status = ''
            for line in out[1].split('\n'):
                if line.startswith('Grants for'):
                    continue
                elif line is '' or line is ' ':
                    continue
                else:
                    parse.append(line.split(' IDENT')[0])
            for line in parse:
                status += line + '\n'
            return status
        elif action == 'grant':
            status = shell_cs(
                'mysql -e "GRANT ALL ON %s.* TO \'%s\'@\'localhost\';"' %
                (dbname, user),
                stderr=True)
        elif action == 'revoke':
            status = shell_cs(
                'mysql -e "REVOKE ALL ON %s.* FROM \'%s\'@\'localhost\';"' %
                (dbname, user),
                stderr=True)
        if status[0] >= 1:
            raise Exception(status[1])

    def execute(self, dbname, command):
        return shell('mysql -e "%s" %s' % (command, dbname), stderr=True)

    def get_dbs(self):
        dblist = []
        excludes = [
            'Database', 'information_schema', 'mysql', 'performance_schema'
        ]
        dbs = shell('mysql -e "SHOW DATABASES;"')
        for line in dbs.split('\n'):
            if not line in excludes and line.split():
                dblist.append({
                    'name': line,
                    'type': 'MariaDB',
                    'class': self.__class__
                })
        return dblist

    def get_users(self):
        userlist = []
        excludes = ['root', ' ', '']
        output = shell('mysql -e "SELECT user FROM mysql.user;"')
        for line in output.split('\n')[1:]:
            if not line in userlist and not line in excludes:
                userlist.append({
                    'name': line,
                    'type': 'MariaDB',
                    'class': self.__class__
                })
        return userlist
Exemplo n.º 10
0
class MariaDB(Plugin):
    implements(apis.databases.IDatabase)
    db = None

    def connect(self, store, user='******', passwd='', db=None):
        if db:
            self.db = _mysql.connect('localhost', user, passwd, db)
            store[self.plugin_info.db_name] = self.db
        else:
            try:
                self.db = _mysql.connect('localhost', user, passwd)
            except _mysql_exceptions.OperationalError:
                raise DBAuthFail(self.plugin_info.db_name)
            store[self.plugin_info.db_name] = self.db

    def checkpwstat(self):
        try:
            _mysql.connect('localhost', 'root', '')
            return False
        except:
            return True

    def chpwstat(self, newpasswd, conn=None):
        if not self.db and conn:
            self.db = conn
        self.db.query('USE mysql')
        self.db.query('UPDATE user SET password=PASSWORD("' + newpasswd +
                      '") WHERE User=\'root\'')
        self.db.query('FLUSH PRIVILEGES')

    def validate(self, name='', user='', passwd='', conn=None):
        if not self.db and conn:
            self.db = conn
        if name and re.search('\.|-|`|\\\\|\/|^test$|[ ]', name):
            raise Exception(
                'Database name must not contain spaces, dots, dashes or other special characters'
            )
        elif name and len(name) > 16:
            raise Exception('Database name must be shorter than 16 characters')
        if user and re.search('\.|-|`|\\\\|\/|^test$|[ ]', user):
            raise Exception(
                'Database username must not contain spaces, dots, dashes or other special characters'
            )
        elif user and len(user) > 16:
            raise Exception(
                'Database username must be shorter than 16 characters')
        if passwd and len(passwd) < 8:
            raise Exception(
                'Database password must be longer than 8 characters')
        if name:
            for x in self.get_dbs():
                if x['name'] == name:
                    raise Exception(
                        'You already have a database named %s - please remove that one or choose a new name!'
                        % name)
        if user:
            for x in self.get_users():
                if x['name'] == user:
                    raise Exception(
                        'You already have a database user named %s - please remove that one or choose a new name!'
                        % user)
        return True

    def add(self, dbname, conn=None):
        if not self.db and conn:
            self.db = conn
        self.validate(name=dbname, user=dbname)
        self.db.query('CREATE DATABASE %s' % dbname)

    def remove(self, dbname, conn=None):
        if not self.db and conn:
            self.db = conn
        if self.db:
            self.db.query('DROP DATABASE %s' % dbname)
        else:
            raise DBConnFail(self.plugin_info.db_name)

    def usermod(self, user, action, passwd, conn=None):
        if not self.db and conn:
            self.db = conn
        if action == 'add' and self.db:
            self.validate(user=user, passwd=passwd)
            self.db.query(
                'CREATE USER \'%s\'@\'localhost\' IDENTIFIED BY \'%s\'' %
                (user, passwd))
        elif action == 'del' and self.db:
            self.db.query('DROP USER \'%s\'@\'localhost\'' % user)
        else:
            raise Exception('Unknown input or database connection failure')

    def chperm(self, dbname, user, action, conn=None):
        if not self.db and conn:
            self.db = conn
        if action == 'check' and self.db:
            self.db.query('SHOW GRANTS FOR \'%s\'@\'localhost\'' % user)
            r = self.db.store_result()
            out = r.fetch_row(0)
            parse = []
            status = ''
            for line in out:
                if line[0].startswith('Grants for'):
                    continue
                elif line[0] is '' or line[0] is ' ':
                    continue
                else:
                    parse.append(line[0].split(' IDENT')[0])
            for line in parse:
                status += line + '\n'
            return status
        elif action == 'grant' and self.db:
            self.db.query('GRANT ALL ON %s.* TO \'%s\'@\'localhost\'' %
                          (dbname, user))
        elif action == 'revoke' and self.db:
            self.db.query('REVOKE ALL ON %s.* FROM \'%s\'@\'localhost\'' %
                          (dbname, user))
        else:
            raise Exception('Unknown input or database connection failure')

    def execute(self, dbname, command, conn=None):
        if not self.db and conn:
            self.db = conn
        cmds = command.split(';')
        if self.db:
            self.db.query('USE %s' % dbname)
            parse = []
            for x in cmds:
                if x.split():
                    self.db.query('%s' % x)
                    r = self.db.store_result()
                    if r:
                        out = r.fetch_row(0)
                        for line in out:
                            parse.append(line[0])
            status = ''
            for line in parse:
                status += line + '\n'
            return status
        else:
            raise DBConnFail(self.plugin_info.db_name)

    def get_dbs(self, conn=None):
        dblist = []
        excludes = [
            'Database', 'information_schema', 'mysql', 'performance_schema'
        ]
        if not self.db and conn:
            self.db = conn
        if self.db:
            self.db.query('SHOW DATABASES')
            r = self.db.store_result()
            dbs = r.fetch_row(0)
        else:
            raise DBConnFail(self.plugin_info.db_name)
        for db in dbs:
            if not db[0] in excludes and db[0].split():
                dblist.append({
                    'name': db[0],
                    'type': 'MariaDB',
                    'class': self.__class__
                })
        return dblist

    def get_users(self, conn=None):
        userlist = []
        excludes = ['root', ' ', '']
        if not self.db and conn:
            self.db = conn
        if self.db:
            self.db.query('SELECT user FROM mysql.user')
            r = self.db.store_result()
            output = r.fetch_row(0)
        else:
            raise DBConnFail(self.plugin_info.db_name)
        for usr in output:
            if not usr[0] in userlist and not usr[0] in excludes:
                userlist.append({
                    'name': usr[0],
                    'type': 'MariaDB',
                    'class': self.__class__
                })
        return userlist
Exemplo n.º 11
0
class PythonLangAssist(Plugin):
    implements(apis.langassist.ILangMgr)
    name = 'Python'

    def install(self, *mods):
        s = shell_cs('pip%s install %s' % \
            ('2' if self.app.platform in ['arkos', 'arch'] else '',
                ' '.join(x for x in mods)))
        if s[0] != 0:
            self.app.log.error('Failed to install %s via PyPI; %s' %
                               (' '.join(x for x in mods), s[1]))
            raise Exception(
                'Failed to install %s via PyPI, check logs for info' %
                ' '.join(x for x in mods))

    def remove(self, *mods):
        s = shell_cs('pip%s uninstall %s' % \
            ('2' if self.app.platform in ['arkos', 'arch'] else '',
                ' '.join(x for x in mods)))
        if s[0] != 0:
            self.app.log.error('Failed to remove %s via PyPI; %s' %
                               (' '.join(x for x in mods), s[1]))
            raise Exception(
                'Failed to remove %s via PyPI, check logs for info' %
                ' '.join(x for x in mods))

    def is_installed(self, name):
        s = shell('pip%s freeze' %
                  '2' if self.app.platform in ['arkos', 'arch'] else '')
        for x in s.split('\n'):
            if name in x.split('==')[0]:
                return True
        return False

    def add_django_site(self, name, path, user, group):
        shell('cd %s; django-admin.py startproject %s' % (path, name))
        gconf = '#! /bin/bash\n\n'
        gconf += 'NAME="%s"\n' % name
        gconf += 'SOCKFILE=%s\n' % os.path.join(path, 'gunicorn.sock')
        gconf += 'USER=%s\n' % user
        gconf += 'GROUP=%s\n' % group
        gconf += 'NUM_WORKERS=3\n'
        gconf += 'DJANGODIR=%s\n' % path
        gconf += 'DJANGO_SETTINGS_MODULE=%s.settings\n' % name
        gconf += 'DJANGO_WSGI_MODULE=%s.wsgi\n\n' % name
        gconf += 'export PYTHONPATH=$DJANGODIR:$PYTHONPATH\n\n'
        gconf += 'echo "Starting $NAME as `whoami`"\n\n'
        gconf += 'exec gunicorn ${DJANGO_WSGI_MODULE}:application \ \n'
        gconf += '--name $NAME --workers $NUM_WORKERS \ \n'
        gconf += '--user=$USER --group=$GROUP \ \n'
        gconf += '--log-level=debug --bind=unix:$SOCKFILE\n'
        open(os.path.join(path, 'gunicorn'), 'w').write(gconf)
        st = os.stat(os.path.join(path, 'gunicorn'))
        os.chmod(os.path.join(path, 'gunicorn'), st.st_mode | 0111)
        s = self.app.get_backend(apis.services.IServiceManager)
        s.edit(
            name, {
                'stype': 'program',
                'directory': path,
                'user': user,
                'command': os.path.join(path, 'gunicorn'),
                'stdout_logfile': os.path.join(path, '%s_logfile.log' % name),
                'stderr_logfile': os.path.join(path, '%s_logfile.log' % name)
            })
        s.enable(name, 'supervisor')

    def remove_django_site(self, name, path):
        s = self.app.get_backend(apis.services.IServiceManager)
        s.delete(name, 'supervisor')
        shutil.rmtree(path)
Exemplo n.º 12
0
class ownCloud(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Key('error_page', '403 = /core/templates/403.php'),
        nginx.Key('error_page', '404 = /core/templates/404.php'),
        nginx.Key('client_max_body_size', '10G'),
        nginx.Key('fastcgi_buffers', '64 4K'),
        nginx.Key('rewrite', '^/caldav(.*)$ /remote.php/caldav$1 redirect'),
        nginx.Key('rewrite', '^/carddav(.*)$ /remote.php/carddav$1 redirect'),
        nginx.Key('rewrite', '^/webdav(.*)$ /remote.php/webdav$1 redirect'),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('~ ^/(data|config|\.ht|db_structure\.xml|README)',
                       nginx.Key('deny', 'all')),
        nginx.Location(
            '/',
            nginx.Key(
                'rewrite',
                '^/.well-known/host-meta /public.php?service=host-meta last'),
            nginx.Key(
                'rewrite',
                '^/.well-known/host-meta.json /public.php?service=host-meta-json last'
            ),
            nginx.Key('rewrite',
                      '^/.well-known/carddav /remote.php/carddav/ redirect'),
            nginx.Key('rewrite',
                      '^/.well-known/caldav /remote.php/caldav/ redirect'),
            nginx.Key('rewrite', '^(/core/doc/[^\/]+/)$ $1/index.html'),
            nginx.Key('try_files', '$uri $uri/ index.php')),
        nginx.Location(
            '~ ^(.+?\.php)(/.*)?$', nginx.Key('try_files', '$1 = 404'),
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_param', 'SCRIPT_FILENAME $document_root$1'),
            nginx.Key('fastcgi_param', 'PATH_INFO $2'),
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_read_timeout', '900s')),
        nginx.Location('~* ^.+\.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)$',
                       nginx.Key('expires', '30d'),
                       nginx.Key('access_log', 'off'))
    ]

    def pre_install(self, name, vars):
        dbname = vars.getvalue('oc-dbname', '')
        dbpasswd = vars.getvalue('oc-dbpasswd', '')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        if dbname and dbpasswd:
            apis.databases(self.app).get_interface('MariaDB').validate(
                dbname, dbname, dbpasswd, conn)
        elif dbname:
            raise Exception(
                'You must enter a database password if you specify a database name!'
            )
        elif dbpasswd:
            raise Exception(
                'You must enter a database name if you specify a database password!'
            )
        if vars.getvalue('oc-username', '') == '':
            raise Exception('Must choose an ownCloud username')
        elif vars.getvalue('oc-logpasswd', '') == '':
            raise Exception('Must choose an ownCloud password')

    def post_install(self, name, path, vars):
        phpctl = apis.langassist(self.app).get_interface('PHP')
        datadir = ''
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        if vars.getvalue('oc-dbname', '') == '':
            dbname = name
        else:
            dbname = vars.getvalue('oc-dbname')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        if vars.getvalue('oc-dbpasswd', '') == '':
            passwd = secret_key[0:8]
        else:
            passwd = vars.getvalue('oc-dbpasswd')
        username = vars.getvalue('oc-username')
        logpasswd = vars.getvalue('oc-logpasswd')

        # Request a database and user to interact with it
        dbase.add(dbname, conn)
        dbase.usermod(dbname, 'add', passwd, conn)
        dbase.chperm(dbname, dbname, 'grant', conn)

        # Set ownership as necessary
        if not os.path.exists(os.path.join(path, 'data')):
            os.makedirs(os.path.join(path, 'data'))
        shell('chown -R http:http ' + os.path.join(path, 'apps'))
        shell('chown -R http:http ' + os.path.join(path, 'data'))
        shell('chown -R http:http ' + os.path.join(path, 'config'))

        # If there is a custom path for the data directory, do the magic
        if vars.getvalue('oc-ddir', '') != '':
            datadir = vars.getvalue('oc-ddir')
            if not os.path.exists(
                    os.path.join(datadir if datadir else path, 'data')):
                os.makedirs(os.path.join(datadir if datadir else path, 'data'))
            shell('chown -R http:http ' +
                  os.path.join(datadir if datadir else path, 'data'))
            phpctl.open_basedir('add', datadir)

        # Create ownCloud automatic configuration file
        f = open(os.path.join(path, 'config', 'autoconfig.php'), 'w')
        f.write('<?php\n'
                '   $AUTOCONFIG = array(\n'
                '   "adminlogin" => "' + username + '",\n'
                '   "adminpass" => "' + logpasswd + '",\n'
                '   "dbtype" => "mysql",\n'
                '   "dbname" => "' + dbname + '",\n'
                '   "dbuser" => "' + dbname + '",\n'
                '   "dbpass" => "' + passwd + '",\n'
                '   "dbhost" => "localhost",\n'
                '   "dbtableprefix" => "",\n'
                '   "directory" => "' +
                os.path.join(datadir if datadir else path, 'data') + '",\n'
                '   );\n'
                '?>\n')
        f.close()
        shell('chown http:http ' +
              os.path.join(path, 'config', 'autoconfig.php'))

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

        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        f = open('/etc/php/conf.d/xcache.ini', 'w')
        oc = [
            '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'
        ]
        f.writelines(oc)
        f.close()

        # Return an explicatory message
        if detect_architecture()[1] == 'Raspberry Pi':
            return (
                'ownCloud takes a long time to set up on the RPi. '
                'Once you open the page for the first time, it may take 5-10 '
                'minutes for the content to appear. Please do not refresh the '
                'page.')

    def pre_remove(self, name, path):
        datadir = ''
        dbname = name
        if os.path.exists(os.path.join(path, 'config', 'config.php')):
            f = open(os.path.join(path, 'config', 'config.php'), 'r')
            for line in f.readlines():
                if 'dbname' in line:
                    data = line.split('\'')[1::2]
                    dbname = data[1]
                elif 'datadirectory' in line:
                    data = line.split('\'')[1::2]
                    datadir = data[1]
            f.close()
        elif os.path.exists(os.path.join(path, 'config', 'autoconfig.php')):
            f = open(os.path.join(path, 'config', 'autoconfig.php'), 'r')
            for line in f.readlines():
                if 'dbname' in line:
                    data = line.split('\"')[1::2]
                    dbname = data[1]
                elif 'directory' in line:
                    data = line.split('\'')[1::2]
                    datadir = data[1]
            f.close()
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        dbase.remove(dbname, conn)
        dbase.usermod(dbname, 'del', '', conn)
        if datadir:
            shutil.rmtree(datadir)
            phpctl.open_basedir('del', datadir)

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        # First, force SSL in ownCloud's config file
        if os.path.exists(os.path.join(path, 'config', 'config.php')):
            px = os.path.join(path, 'config', 'config.php')
        else:
            px = os.path.join(path, 'config', 'autoconfig.php')
        ic = open(px, 'r').readlines()
        f = open(px, 'w')
        oc = []
        found = False
        for l in ic:
            if '"forcessl" =>' in l:
                l = '"forcessl" => true,\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            for x in enumerate(oc):
                if '"dbhost" =>' in x[1]:
                    oc.insert(x[0] + 1, '"forcessl" => true,\n')
        f.writelines(oc)
        f.close()

        # Next, update the ca-certificates thing to include our cert
        # (if necessary)
        if not os.path.exists('/usr/share/ca-certificates'):
            try:
                os.makedirs('/usr/share/ca-certificates')
            except OSError, e:
                if e.errno == errno.EEXIST and os.path.isdir(
                        '/usr/share/ca-certificates'):
                    pass
                else:
                    raise
        shutil.copy(cfile, '/usr/share/ca-certificates/')
        fname = cfile.rstrip('/').split('/')[-1]
        ic = open('/etc/ca-certificates.conf', 'r').readlines()
        f = open('/etc/ca-certificates.conf', 'w')
        oc = []
        for l in ic:
            if l != fname + '\n':
                oc.append(l)
        oc.append(fname + '\n')
        f.writelines(oc)
        f.close()
        shell('update-ca-certificates')