def _nginx_conf_create(self): from time import strftime from submin.template.shortcuts import evaluate template = str(self.init_vars['output']) if template.endswith('.conf'): template = template[:-len('.conf')] fname_submin_wsgi = template + '-webui-wsgi.conf' fname_uwsgi_ini = template + '-webui-uwsgi.ini' self.init_vars['submin_wsgi'] = fname_submin_wsgi self.init_vars['uwsgi_ini'] = fname_uwsgi_ini self.init_vars['datetime_generated'] = strftime("%Y-%m-%d %H:%M:%S") header_webui = evaluate('subminadmin/nginx-header.conf', self.init_vars) submin_wsgi = evaluate('subminadmin/nginx-webui-wsgi.conf', self.init_vars) uwsgi_ini = evaluate('subminadmin/uwsgi-webui.ini', self.init_vars) file(fname_submin_wsgi, 'w').write(header_webui + submin_wsgi) file(fname_uwsgi_ini, 'w').write(uwsgi_ini) print 'Nginx files created:\n', "\n".join( [fname_submin_wsgi, fname_uwsgi_ini]) print '''
def _apache_conf_create(self): from time import strftime from submin.template.shortcuts import evaluate self.init_vars['datetime_generated'] = strftime("%Y-%m-%d %H:%M:%S") if 'PYTHONPATH' in os.environ: self.init_vars['setenv_pythonpath'] = 'SetEnv PYTHONPATH %s' % os.environ['PYTHONPATH'] else: self.init_vars['setenv_pythonpath'] = '' if self.init_vars['submin_base_url'] == "/": # Doesn't make sense to have an Alias if the base url is "/" self.init_vars['webui_origin'] = 'DocumentRoot "%(www_dir)s"' % self.init_vars else: # The alias is really picky about trailing slashes. Our experience # finds that no trailing slashes works best for both src and dst. # This is because without a trailing slash, the following will also # work as expected: http://localhost/submin submin_base_url = str(self.init_vars['submin_base_url']).rstrip('/') www_dir = str(self.init_vars['www_dir']).rstrip('/') self.init_vars['webui_origin'] = 'Alias "%s" "%s"' % (submin_base_url, www_dir) generate_configs = [ 'webui-cgi', 'webui-wsgi', 'svn', 'trac-modpython', 'trac-cgi', 'trac-modwsgi', 'trac-fcgid', 'trac-no-anonymous' ] generated = [] basename = str(self.env + 'conf' + 'apache-%s.conf') template = 'subminadmin/apache-%s.conf' for name in generate_configs: fname = basename % name file(fname, 'w').write(evaluate(template % name, self.init_vars)) generated.append(fname) basename = str(self.env + 'conf' + 'apache-2.4-%s.conf') self.init_vars['apache_2_4'] = True for name in generate_configs: fname = basename % name file(fname, 'w').write(evaluate(template % name, self.init_vars)) generated.append(fname) print 'Apache files created:\n', '\n'.join(generated) print '''
def _apache_conf_create(self): from time import strftime from submin.template.shortcuts import evaluate self.init_vars['datetime_generated'] = strftime("%Y-%m-%d %H:%M:%S") if 'PYTHONPATH' in os.environ: self.init_vars[ 'setenv_pythonpath'] = 'SetEnv PYTHONPATH %s' % os.environ[ 'PYTHONPATH'] else: self.init_vars['setenv_pythonpath'] = '' if self.init_vars['submin_base_url'] == "/": # Doesn't make sense to have an Alias if the base url is "/" self.init_vars[ 'webui_origin'] = 'DocumentRoot "%(www_dir)s"' % self.init_vars else: # The alias is really picky about trailing slashes. Our experience # finds that no trailing slashes works best for both src and dst. # This is because without a trailing slash, the following will also # work as expected: http://localhost/submin submin_base_url = str( self.init_vars['submin_base_url']).rstrip('/') www_dir = str(self.init_vars['www_dir']).rstrip('/') self.init_vars['webui_origin'] = 'Alias "%s" "%s"' % ( submin_base_url, www_dir) generate_configs = [ 'webui-cgi', 'webui-wsgi', 'svn', 'trac-modpython', 'trac-cgi', 'trac-modwsgi', 'trac-fcgid', 'trac-no-anonymous' ] generated = [] basename = str(self.env + 'conf' + 'apache-%s.conf') template = 'subminadmin/apache-%s.conf' for name in generate_configs: fname = basename % name file(fname, 'w').write(evaluate(template % name, self.init_vars)) generated.append(fname) basename = str(self.env + 'conf' + 'apache-2.4-%s.conf') self.init_vars['apache_2_4'] = True for name in generate_configs: fname = basename % name file(fname, 'w').write(evaluate(template % name, self.init_vars)) generated.append(fname) print 'Apache files created:\n', '\n'.join(generated) print '''
def _apache_conf_create(self): from time import strftime from submin.template.shortcuts import evaluate self.init_vars['datetime_generated'] = strftime("%Y-%m-%d %H:%M:%S") if 'PYTHONPATH' in os.environ: self.init_vars[ 'setenv_pythonpath'] = 'SetEnv PYTHONPATH %s' % os.environ[ 'PYTHONPATH'] else: self.init_vars['setenv_pythonpath'] = '' if self.init_vars['submin_base_url'] == "/": # Doesn't make sense to have an Alias if the base url is "/" self.init_vars[ 'webui_origin'] = 'DocumentRoot "%(www_dir)s"' % self.init_vars else: # The alias is really picky about trailing slashes. Our experience # finds that no trailing slashes works best for both src and dst. # This is because without a trailing slash, the following will also # work as expected: http://localhost/submin submin_base_url = str( self.init_vars['submin_base_url']).rstrip('/') www_dir = str(self.init_vars['www_dir']).rstrip('/') self.init_vars['webui_origin'] = 'Alias "%s" "%s"' % ( submin_base_url, www_dir) generate_configs = [ 'webui-cgi', 'webui-wsgi', 'svn', 'trac-modpython', 'trac-cgi', 'trac-modwsgi', 'trac-fcgid', 'trac-no-anonymous' ] generated = [] # Apache 1.x is not supported any more, so we can leave this out. #basename = str(self.env + 'conf' + 'apache-%s.conf') #template = 'subminadmin/apache-%s.conf' #for name in generate_configs: # fname = basename % name # open(fname, 'w').write(evaluate(template % name, self.init_vars)) # generated.append(fname) basename = str(self.env + 'conf' + 'apache-2.4-%s.conf') self.init_vars['apache_2_4'] = True for name in generate_configs: fname = basename % name open(fname, 'w').write(evaluate(template % name, self.init_vars)) generated.append(fname) print('Apache files created:\n', '\n'.join(generated)) print(''' Please include ONE of the -webui- files and optionally -trac- and -svn- files (if you need/want that functionality). The -trac-no-anonymous.conf file can be used together with ONE other trac config file. The -2.4- files are for apache >= 2.4. Hint: cgi is simpler, but performs worse. Please read the instructions in the file for caveats and on how to include! ''')
def run(self): from submin.models import options from submin.template.shortcuts import evaluate from submin.diagnostics import trac, git, svn, email localvars = {} diagnostics = {} if len(self.argv) > 0: which = self.argv[0] else: which = 'all' if which in ('all', 'email'): diagnostics.update(email.diagnostics()) if which in ('all', 'git'): diagnostics.update(git.diagnostics()) if which in ('all', 'svn'): diagnostics.update(svn.diagnostics()) if which in ('all', 'trac'): diagnostics.update(trac.diagnostics()) localvars['diag'] = diagnostics localvars['subminenv'] = options.env_path() formatted = evaluate('diagnostics.%s.print' % (which,), localvars) print(formatted)
def email_user(self, key=None, password=None, origin=None): """Email the user a key (to reset her password) OR a password (if the user followed a link with the key in it). The origin shows where the request came from (string)""" from submin.template.shortcuts import evaluate from submin.email import sendmail if key and password: raise ValueError('Ambiguous input: both key and password are set') templatevars = { 'from': options.value('smtp_from', 'root@localhost'), 'to': self.email, 'username': self.name, 'key': key, 'password': password, 'http_vhost': options.http_vhost(), 'base_url': options.url_path("base_url_submin"), 'origin': origin, } if key: template = 'email/prepare_reset.txt' else: template = 'email/reset_password.txt' message = evaluate(template, templatevars) sendmail(templatevars['from'], templatevars['to'], message)
def setTracSyncHook(reponame, enable): prepare(reponame) hook_dir = repository.directory('git', reponame) + 'hooks' hook = hook_dir + 'post-receive.d' + '002-trac-sync.hook' try: os.unlink(hook) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError( "Removing trac-sync hook failed: %s" % (str(e), )) if not enable: return variables = { 'submin_env': str(options.env_path()), 'repository': reponame, 'hook_version': HOOK_VERSIONS['trac-sync'], } contents = evaluate('plugins/vcs/git/trac-sync', variables) with file(hook, 'w') as f: f.writelines(contents) os.chmod(hook, 0o755)
def run(self): from submin.models import options from submin.template.shortcuts import evaluate from submin.diagnostics import trac, git, svn, email localvars = {} diagnostics = {} if len(self.argv) > 0: which = self.argv[0] else: which = 'all' if which in ('all', 'email'): diagnostics.update(email.diagnostics()) if which in ('all', 'git'): diagnostics.update(git.diagnostics()) if which in ('all', 'svn'): diagnostics.update(svn.diagnostics()) if which in ('all', 'trac'): diagnostics.update(trac.diagnostics()) localvars['diag'] = diagnostics localvars['subminenv'] = options.env_path() formatted = evaluate('diagnostics.%s.print' % (which, ), localvars) print(formatted)
def setTracSyncHook(reponame, enable): prepare(reponame) hook_dir = repository.directory('git', reponame) + 'hooks' hook = hook_dir + 'post-receive.d' + '002-trac-sync.hook' try: os.unlink(hook) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError( "Removing trac-sync hook failed: %s" % (str(e),)) if not enable: return variables = { 'submin_env': str(options.env_path()), 'repository': reponame, 'hook_version': HOOK_VERSIONS['trac-sync'], } contents = evaluate('plugins/vcs/git/trac-sync', variables) with file(hook, 'w') as f: f.writelines(contents) os.chmod(hook, 0o755)
def __init__(self, command, success, text, details=None): from submin.template.shortcuts import evaluate tvars = {"command": command, "success_str": str(success), "text": text, "details": details, "success": success} content = evaluate("ajax/response.xml", tvars) XMLResponse.__init__(self, content)
def __init__(self, errormsg, request=None, details=None): localvars = {} localvars['errormsg'] = html_escape(errormsg) if details: localvars['details'] = html_escape(details) formatted = evaluate('error.html', localvars) Response.__init__(self, formatted)
def export_notifications(**kwargs): """Export a mailer.py config file For each user/repository pair, a config group is created. Only if a user has read or read/write permission to one or multiple paths in that repository, _and_ if the user has notifications enabled for that repository, _and_ if the user has a non-empty email-address. Multiple paths are grouped together by a regexp group (multiple|paths)""" bindir = options.static_path("hooks") + 'svn' # get a list of all users from submin.models import user users = [user.User(name) for name in user.list(user.FakeAdminUser())] groups = [] for u in users: if not u.email: continue u_notif = u.notifications() for repos in u_notif: repos_path = str(options.env_path("svn_dir") + repos) if not u_notif[repos]["enabled"]: continue # strip leading / paths = [ x[1:] for x in permissions.list_readable_user_paths(repos, "svn", u) ] if len(paths) == 0: continue elif len(paths) == 1: for_paths = paths[0] elif len(paths) > 0: for_paths = "(" + "|".join(paths) + ")" # Only match complete path, not partial paths (ticket #257) repos_path_re = '^' + repos_path + '$' g = { "repos_name": repos, "for_repos": repos_path_re, "email": u.email, "for_paths": for_paths, "username": u.name } groups.append(g) email = options.value( 'commit_email_from', 'Please configure commit_email_from <*****@*****.**>') templatevariables = {"groups": groups, 'from_addr': email} from submin.template.shortcuts import evaluate content = evaluate("plugins/vcs/svn/mailer.conf", templatevariables) filename = str((options.env_path() + 'conf') + 'mailer.py.conf') file(filename, 'w').writelines(content.encode('utf-8'))
def evaluate_form(self, msg='', session=None): localvalues = {} localvalues['msg'] = msg localvalues['base_url'] = options.url_path('base_url_submin') if session and 'user' in session and 'is_authenticated' in session['user']: if session['user']['is_authenticated']: localvalues['is_authenticated'] = True localvalues['username'] = session['user']['name'] return Response(evaluate('login.html', localvalues))
def handler(self, request, path): if 'auto_authenticate' in request.session: username = request.session['auto_authenticate'] else: if not request.post: return self.evaluate_form(session=request.session) username = request.post.get('username', '') password = request.post.get('password', '') if '' in (username, password): return self.evaluate_form(session=request.session) invalid_login = True u = None try: u = user.User(username) invalid_login = False except UnknownUserError as e: pass if 'auto_authenticate' in request.session: del request.session['auto_authenticate'] request.session['change_password_hint'] = True else: try: if not u or not u.check_password(password): return self.evaluate_form( 'Not a valid username and password combination') except NoMD5PasswordError as e: return self.evaluate_form(str(e)) if invalid_login: return self.evaluate_form( 'Not a valid username and password combination') if not database_isuptodate(): localvalues = {} request.session['upgrade_user'] = True base_url = options.url_path('base_url_submin') localvalues['base_url'] = str(base_url) localvalues['session_user'] = u return Response(evaluate('database_upgrade.html', localvalues)) url = options.url_path('base_url_submin') if 'redirected_from' in request.session: login_url = options.url_path('base_url_submin') + 'login' url = request.session['redirected_from'] if url.startswith(login_url): url = options.url_path('base_url_submin') session_user = u.session_object() session_user['is_authenticated'] = True request.session['user'] = session_user request.session.cleanup() return Redirect(url, request, store_url=False)
def __init__(self, command, success, text, details=None): from submin.template.shortcuts import evaluate tvars = { 'command': command, 'success_str': str(success), 'text': text, 'details': details, 'success': success } content = evaluate('ajax/response.xml', tvars) XMLResponse.__init__(self, content)
def handler(self, request, path): if 'auto_authenticate' in request.session: username = request.session['auto_authenticate'] else: if not request.post: return self.evaluate_form(session=request.session) username = request.post.get('username', '') password = request.post.get('password', '') invalid_login = True u = None try: u = user.User(username) invalid_login = False except UnknownUserError as e: pass if 'auto_authenticate' in request.session: del request.session['auto_authenticate'] request.session['change_password_hint'] = True else: try: if not u or not u.check_password(password): return self.evaluate_form('Not a valid username and password combination') except NoMD5PasswordError as e: return self.evaluate_form(str(e)) if invalid_login: return self.evaluate_form('Not a valid username and password combination') if not database_isuptodate(): localvalues = {} request.session['upgrade_user'] = True base_url = options.url_path('base_url_submin') localvalues['base_url'] = str(base_url) localvalues['session_user'] = u return Response(evaluate('database_upgrade.html', localvalues)) url = options.url_path('base_url_submin') if 'redirected_from' in request.session: login_url = options.url_path('base_url_submin') + 'login' url = request.session['redirected_from'] if url.startswith(login_url): url = options.url_path('base_url_submin') session_user = u.session_object() session_user['is_authenticated'] = True request.session['user'] = session_user request.session.cleanup() return Redirect(url, request, store_url=False)
def setCommitEmailHook(reponame, enable): prepare(reponame) reposdir = repository.directory('git', reponame) hook_dir = reposdir + 'hooks' + 'post-receive.d' mkdirs(hook_dir) hook_dest = hook_dir + '001-commit-email.hook' if enable: variables = { 'submin_lib_dir': options.lib_path(), 'base_url': options.url_path('base_url_submin'), 'http_vhost': options.http_vhost(), 'hook_version': HOOK_VERSIONS['commit-email'], } hook = evaluate('plugins/vcs/git/post-receive', variables) try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise try: with file(hook_dest, 'w') as f: f.write(hook) os.chmod(hook_dest, 0o755) except OSError as e: raise repository.PermissionError("Enabling hook failed: %s" % (str(e), )) try: cfg = repository.directory('git', reponame) + 'config' email = options.value( 'commit_email_from', 'Please configure commit_email_from <*****@*****.**>') set_git_config(cfg, 'multimailhook.emailmaxlines', '2000') prefix = '[%s]' % reponame set_git_config(cfg, 'multimailhook.emailprefix', prefix) set_git_config(cfg, 'multimailhook.envelopesender', email) except SetGitConfigError as e: raise repository.PermissionError( "Enabling hook succeeded, but configuring it failed: %s" % (str(e))) else: try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError("Removing hook failed: %s" % (str(e), ))
def handler(self, req, path): localvars = {} localvars['uptodated'] = True localvars['base_url'] = options.url_path('base_url_submin') if database_isuptodate(): localvars['alreadyuptodate'] = True else: database_evolve() localvars['alreadyuptodate'] = False formatted = evaluate('database_upgrade.html', localvars) return Response(formatted)
def setCommitEmailHook(reponame, enable): prepare(reponame) reposdir = repository.directory('git', reponame) hook_dir = reposdir + 'hooks' + 'post-receive.d' mkdirs(hook_dir) hook_dest = hook_dir + '001-commit-email.hook' if enable: variables = { 'submin_lib_dir': options.lib_path(), 'base_url': options.url_path('base_url_submin'), 'http_vhost': options.http_vhost(), 'hook_version': HOOK_VERSIONS['commit-email'], } hook = evaluate('plugins/vcs/git/post-receive', variables) try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise try: with file(hook_dest, 'w') as f: f.write(hook) os.chmod(hook_dest, 0o755) except OSError as e: raise repository.PermissionError( "Enabling hook failed: %s" % (str(e),)) try: cfg = repository.directory('git', reponame) + 'config' email = options.value('commit_email_from', 'Please configure commit_email_from <*****@*****.**>') set_git_config(cfg, 'multimailhook.emailmaxlines', '2000') prefix = '[%s]' % reponame set_git_config(cfg, 'multimailhook.emailprefix', prefix) set_git_config(cfg, 'multimailhook.envelopesender', email) except SetGitConfigError as e: raise repository.PermissionError( "Enabling hook succeeded, but configuring it failed: %s" % (str(e))) else: try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError( "Removing hook failed: %s" % (str(e),))
def _nginx_conf_create(self): from time import strftime from submin.template.shortcuts import evaluate template = str(self.init_vars['output']) if template.endswith('.conf'): template = template[:-len('.conf')] fname_submin_wsgi = template + '-webui-wsgi.conf' fname_uwsgi_ini = template + '-webui-uwsgi.ini' self.init_vars['submin_wsgi'] = fname_submin_wsgi self.init_vars['uwsgi_ini'] = fname_uwsgi_ini self.init_vars['datetime_generated'] = strftime("%Y-%m-%d %H:%M:%S") header_webui = evaluate('subminadmin/nginx-header.conf', self.init_vars) submin_wsgi = evaluate('subminadmin/nginx-webui-wsgi.conf', self.init_vars) uwsgi_ini = evaluate('subminadmin/uwsgi-webui.ini', self.init_vars) file(fname_submin_wsgi, 'w').write(header_webui + submin_wsgi) file(fname_uwsgi_ini, 'w').write(uwsgi_ini) print 'Nginx files created:\n', "\n".join([fname_submin_wsgi, fname_uwsgi_ini]) print '''
def send_email(self, req, path): templatevars = { 'base_url': options.url_path('base_url_submin') } username = req.post.get('username', '') if username: try: u = user.User(username) u.prepare_password_reset(req.remote_address) templatevars['sent'] = True except UnknownUserError: templatevars['sent'] = True else: templatevars['form'] = True formatted = evaluate('password.html', templatevars) return Response(formatted)
def export_notifications(**kwargs): """Export a mailer.py config file For each user/repository pair, a config group is created. Only if a user has read or read/write permission to one or multiple paths in that repository, _and_ if the user has notifications enabled for that repository, _and_ if the user has a non-empty email-address. Multiple paths are grouped together by a regexp group (multiple|paths)""" bindir = options.static_path("hooks") + 'svn' # get a list of all users from submin.models import user users = [user.User(name) for name in user.list(user.FakeAdminUser())] groups = [] for u in users: if not u.email: continue u_notif = u.notifications() for repos in u_notif: repos_path = str(options.env_path("svn_dir") + repos) if not u_notif[repos]["enabled"]: continue # strip leading / paths = [x[1:] for x in permissions.list_readable_user_paths(repos, "svn", u)] if len(paths) == 0: continue elif len(paths) == 1: for_paths = paths[0] elif len(paths) > 0: for_paths = "(" + "|".join(paths) + ")" # Only match complete path, not partial paths (ticket #257) repos_path_re = '^' + repos_path + '$' g = {"repos_name": repos, "for_repos": repos_path_re, "email": u.email, "for_paths": for_paths, "username": u.name} groups.append(g) email = options.value('commit_email_from', 'Please configure commit_email_from <*****@*****.**>') templatevariables = {"groups": groups, 'from_addr': email} from submin.template.shortcuts import evaluate content = evaluate("plugins/vcs/svn/mailer.conf", templatevariables) filename = str((options.env_path() + 'conf') + 'mailer.py.conf') file(filename, 'w').writelines(content.encode('utf-8'))
def reset_password(self, req, username, key): templatevars = { 'base_url': options.url_path('base_url_submin') } if 'auto_authenticate' in req.session: del req.session['auto_authenticate'] try: u = user.User(username) except UnknownUserError: raise if not u.valid_password_reset_key(key): templatevars['invalid'] = True else: templatevars['reset'] = True req.session['auto_authenticate'] = username u.clear_password_reset_key() formatted = evaluate('password.html', templatevars) return Response(formatted)
def __init__(self, template, templatevariables): from submin.template.shortcuts import evaluate content = evaluate(template, templatevariables) XMLResponse.__init__(self, content)
def run(self): if len(self.argv) > 0 and self.argv[0] == 'verbose': formatted = evaluate('external.sync.print', external_sync()) print(formatted) else: external_sync()