db_manage.py
678 lines
| 23.2 KiB
| text/x-python
|
PythonLexer
r5088 | # Copyright (C) 2010-2023 RhodeCode GmbH | |||
r1 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
""" | ||||
Database creation, and setup module for RhodeCode Enterprise. Used for creation | ||||
of database as well as for migration operations | ||||
""" | ||||
import os | ||||
import sys | ||||
import time | ||||
import uuid | ||||
import logging | ||||
import getpass | ||||
from os.path import dirname as dn, join as jn | ||||
from sqlalchemy.engine import create_engine | ||||
from rhodecode import __dbversion__ | ||||
from rhodecode.model import init_model | ||||
from rhodecode.model.user import UserModel | ||||
from rhodecode.model.db import ( | ||||
User, Permission, RhodeCodeUi, RhodeCodeSetting, UserToPerm, | ||||
DbMigrateVersion, RepoGroup, UserRepoGroupToPerm, CacheKey, Repository) | ||||
from rhodecode.model.meta import Session, Base | ||||
from rhodecode.model.permission import PermissionModel | ||||
from rhodecode.model.repo import RepoModel | ||||
from rhodecode.model.repo_group import RepoGroupModel | ||||
from rhodecode.model.settings import SettingsModel | ||||
log = logging.getLogger(__name__) | ||||
def notify(msg): | ||||
""" | ||||
Notification for migrations messages | ||||
""" | ||||
ml = len(msg) + (4 * 2) | ||||
r5085 | print((('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)).upper())) | |||
r1 | ||||
class DbManage(object): | ||||
def __init__(self, log_sql, dbconf, root, tests=False, | ||||
r5085 | SESSION=None, cli_args=None, enc_key=b''): | |||
r1 | self.dbname = dbconf.split('/')[-1] | |||
self.tests = tests | ||||
self.root = root | ||||
self.dburi = dbconf | ||||
self.log_sql = log_sql | ||||
r2339 | self.cli_args = cli_args or {} | |||
r5085 | self.sa = None | |||
self.engine = None | ||||
self.enc_key = enc_key | ||||
# sets .sa .engine | ||||
r1 | self.init_db(SESSION=SESSION) | |||
r5085 | ||||
r1 | self.ask_ok = self.get_ask_ok_func(self.cli_args.get('force_ask')) | |||
r4618 | def db_exists(self): | |||
if not self.sa: | ||||
self.init_db() | ||||
try: | ||||
self.sa.query(RhodeCodeUi)\ | ||||
.filter(RhodeCodeUi.ui_key == '/')\ | ||||
.scalar() | ||||
return True | ||||
except Exception: | ||||
return False | ||||
finally: | ||||
self.sa.rollback() | ||||
r1 | def get_ask_ok_func(self, param): | |||
if param not in [None]: | ||||
# return a function lambda that has a default set to param | ||||
return lambda *args, **kwargs: param | ||||
else: | ||||
from rhodecode.lib.utils import ask_ok | ||||
return ask_ok | ||||
def init_db(self, SESSION=None): | ||||
r5085 | ||||
r1 | if SESSION: | |||
self.sa = SESSION | ||||
r5085 | self.engine = SESSION.bind | |||
r1 | else: | |||
# init new sessions | ||||
engine = create_engine(self.dburi, echo=self.log_sql) | ||||
r5085 | init_model(engine, encryption_key=self.enc_key) | |||
r1 | self.sa = Session() | |||
r5085 | self.engine = engine | |||
r1 | ||||
def create_tables(self, override=False): | ||||
""" | ||||
Create a auth database | ||||
""" | ||||
log.info("Existing database with the same name is going to be destroyed.") | ||||
log.info("Setup command will run DROP ALL command on that database.") | ||||
r5085 | engine = self.engine | |||
r1 | if self.tests: | |||
destroy = True | ||||
else: | ||||
destroy = self.ask_ok('Are you sure that you want to destroy the old database? [y/n]') | ||||
if not destroy: | ||||
r4816 | log.info('db tables bootstrap: Nothing done.') | |||
r1 | sys.exit(0) | |||
if destroy: | ||||
r5085 | Base.metadata.drop_all(bind=engine) | |||
r1 | ||||
checkfirst = not override | ||||
r5085 | Base.metadata.create_all(bind=engine, checkfirst=checkfirst) | |||
r3061 | log.info('Created tables for %s', self.dbname) | |||
r1 | ||||
def set_db_version(self): | ||||
ver = DbMigrateVersion() | ||||
ver.version = __dbversion__ | ||||
ver.repository_id = 'rhodecode_db_migrations' | ||||
ver.repository_path = 'versions' | ||||
self.sa.add(ver) | ||||
r3061 | log.info('db version set to: %s', __dbversion__) | |||
r1 | ||||
r3847 | def run_post_migration_tasks(self): | |||
r1 | """ | |||
Run various tasks before actually doing migrations | ||||
""" | ||||
# delete cache keys on each upgrade | ||||
total = CacheKey.query().count() | ||||
log.info("Deleting (%s) cache keys now...", total) | ||||
CacheKey.delete_all_cache() | ||||
r2653 | def upgrade(self, version=None): | |||
r1 | """ | |||
Upgrades given database schema to given revision following | ||||
all needed steps, to perform the upgrade | ||||
""" | ||||
from rhodecode.lib.dbmigrate.migrate.versioning import api | ||||
r5085 | from rhodecode.lib.dbmigrate.migrate.exceptions import DatabaseNotControlledError | |||
r1 | ||||
if 'sqlite' in self.dburi: | ||||
r3057 | print( | |||
r1 | '********************** WARNING **********************\n' | |||
'Make sure your version of sqlite is at least 3.7.X. \n' | ||||
'Earlier versions are known to fail on some migrations\n' | ||||
'*****************************************************\n') | ||||
upgrade = self.ask_ok( | ||||
'You are about to perform a database upgrade. Make ' | ||||
'sure you have backed up your database. ' | ||||
'Continue ? [y/n]') | ||||
if not upgrade: | ||||
log.info('No upgrade performed') | ||||
sys.exit(0) | ||||
repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))), | ||||
'rhodecode/lib/dbmigrate') | ||||
db_uri = self.dburi | ||||
r3406 | if version: | |||
DbMigrateVersion.set_version(version) | ||||
r1 | try: | |||
r3406 | curr_version = api.db_version(db_uri, repository_path) | |||
r5085 | msg = (f'Found current database db_uri under version ' | |||
f'control with version {curr_version}') | ||||
r1 | ||||
except (RuntimeError, DatabaseNotControlledError): | ||||
curr_version = 1 | ||||
r5085 | msg = f'Current database is not under version control. ' \ | |||
f'Setting as version {curr_version}' | ||||
r1 | api.version_control(db_uri, repository_path, curr_version) | |||
notify(msg) | ||||
if curr_version == __dbversion__: | ||||
log.info('This database is already at the newest version') | ||||
sys.exit(0) | ||||
r5085 | upgrade_steps = list(range(curr_version + 1, __dbversion__ + 1)) | |||
notify(f'attempting to upgrade database from ' | ||||
f'version {curr_version} to version {__dbversion__}') | ||||
r1 | ||||
# CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE | ||||
r5460 | final_step = 'latest' | |||
r1 | for step in upgrade_steps: | |||
r5085 | notify(f'performing upgrade step {step}') | |||
r1 | time.sleep(0.5) | |||
api.upgrade(db_uri, repository_path, step) | ||||
self.sa.rollback() | ||||
r5085 | notify(f'schema upgrade for step {step} completed') | |||
r1 | ||||
r5460 | final_step = step | |||
r1 | ||||
r3847 | self.run_post_migration_tasks() | |||
r5460 | notify(f'upgrade to version {final_step} successful') | |||
r1 | ||||
def fix_repo_paths(self): | ||||
""" | ||||
Fixes an old RhodeCode version path into new one without a '*' | ||||
""" | ||||
paths = self.sa.query(RhodeCodeUi)\ | ||||
.filter(RhodeCodeUi.ui_key == '/')\ | ||||
.scalar() | ||||
paths.ui_value = paths.ui_value.replace('*', '') | ||||
try: | ||||
self.sa.add(paths) | ||||
self.sa.commit() | ||||
except Exception: | ||||
self.sa.rollback() | ||||
raise | ||||
def fix_default_user(self): | ||||
""" | ||||
Fixes an old default user with some 'nicer' default values, | ||||
used mostly for anonymous access | ||||
""" | ||||
def_user = self.sa.query(User)\ | ||||
r5085 | .filter(User.username == User.DEFAULT_USER)\ | |||
.one() | ||||
r1 | ||||
def_user.name = 'Anonymous' | ||||
def_user.lastname = 'User' | ||||
def_user.email = User.DEFAULT_USER_EMAIL | ||||
try: | ||||
self.sa.add(def_user) | ||||
self.sa.commit() | ||||
except Exception: | ||||
self.sa.rollback() | ||||
raise | ||||
def fix_settings(self): | ||||
""" | ||||
Fixes rhodecode settings and adds ga_code key for google analytics | ||||
""" | ||||
hgsettings3 = RhodeCodeSetting('ga_code', '') | ||||
try: | ||||
self.sa.add(hgsettings3) | ||||
self.sa.commit() | ||||
except Exception: | ||||
self.sa.rollback() | ||||
raise | ||||
def create_admin_and_prompt(self): | ||||
# defaults | ||||
defaults = self.cli_args | ||||
username = defaults.get('username') | ||||
password = defaults.get('password') | ||||
email = defaults.get('email') | ||||
if username is None: | ||||
r5148 | username = input('Specify admin username:') | |||
r1 | if password is None: | |||
password = self._get_admin_password() | ||||
if not password: | ||||
# second try | ||||
password = self._get_admin_password() | ||||
if not password: | ||||
sys.exit() | ||||
if email is None: | ||||
r5148 | email = input('Specify admin email:') | |||
r1 | api_key = self.cli_args.get('api_key') | |||
self.create_user(username, password, email, True, | ||||
strict_creation_check=False, | ||||
api_key=api_key) | ||||
def _get_admin_password(self): | ||||
password = getpass.getpass('Specify admin password ' | ||||
'(min 6 chars):') | ||||
confirm = getpass.getpass('Confirm password:') | ||||
if password != confirm: | ||||
log.error('passwords mismatch') | ||||
return False | ||||
if len(password) < 6: | ||||
log.error('password is too short - use at least 6 characters') | ||||
return False | ||||
return password | ||||
def create_test_admin_and_users(self): | ||||
log.info('creating admin and regular test users') | ||||
from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \ | ||||
TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \ | ||||
TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \ | ||||
TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \ | ||||
TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL | ||||
self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, | ||||
r1482 | TEST_USER_ADMIN_EMAIL, True, api_key=True) | |||
r1 | ||||
self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, | ||||
r1482 | TEST_USER_REGULAR_EMAIL, False, api_key=True) | |||
r1 | ||||
self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, | ||||
r1482 | TEST_USER_REGULAR2_EMAIL, False, api_key=True) | |||
r1 | ||||
def create_ui_settings(self, repo_store_path): | ||||
""" | ||||
Creates ui settings, fills out hooks | ||||
and disables dotencode | ||||
""" | ||||
settings_model = SettingsModel(sa=self.sa) | ||||
r1562 | from rhodecode.lib.vcs.backends.hg import largefiles_store | |||
r1564 | from rhodecode.lib.vcs.backends.git import lfs_store | |||
r1 | ||||
# Build HOOKS | ||||
hooks = [ | ||||
(RhodeCodeUi.HOOK_REPO_SIZE, 'python:vcsserver.hooks.repo_size'), | ||||
# HG | ||||
(RhodeCodeUi.HOOK_PRE_PULL, 'python:vcsserver.hooks.pre_pull'), | ||||
(RhodeCodeUi.HOOK_PULL, 'python:vcsserver.hooks.log_pull_action'), | ||||
(RhodeCodeUi.HOOK_PRE_PUSH, 'python:vcsserver.hooks.pre_push'), | ||||
r1461 | (RhodeCodeUi.HOOK_PRETX_PUSH, 'python:vcsserver.hooks.pre_push'), | |||
r1 | (RhodeCodeUi.HOOK_PUSH, 'python:vcsserver.hooks.log_push_action'), | |||
r1755 | (RhodeCodeUi.HOOK_PUSH_KEY, 'python:vcsserver.hooks.key_push'), | |||
r1 | ||||
] | ||||
for key, value in hooks: | ||||
hook_obj = settings_model.get_ui_by_key(key) | ||||
hooks2 = hook_obj if hook_obj else RhodeCodeUi() | ||||
hooks2.ui_section = 'hooks' | ||||
hooks2.ui_key = key | ||||
hooks2.ui_value = value | ||||
self.sa.add(hooks2) | ||||
# enable largefiles | ||||
largefiles = RhodeCodeUi() | ||||
largefiles.ui_section = 'extensions' | ||||
largefiles.ui_key = 'largefiles' | ||||
largefiles.ui_value = '' | ||||
self.sa.add(largefiles) | ||||
# set default largefiles cache dir, defaults to | ||||
r1562 | # /repo_store_location/.cache/largefiles | |||
r1 | largefiles = RhodeCodeUi() | |||
largefiles.ui_section = 'largefiles' | ||||
largefiles.ui_key = 'usercache' | ||||
r1562 | largefiles.ui_value = largefiles_store(repo_store_path) | |||
r1 | self.sa.add(largefiles) | |||
r1564 | # set default lfs cache dir, defaults to | |||
# /repo_store_location/.cache/lfs_store | ||||
lfsstore = RhodeCodeUi() | ||||
lfsstore.ui_section = 'vcs_git_lfs' | ||||
lfsstore.ui_key = 'store_location' | ||||
lfsstore.ui_value = lfs_store(repo_store_path) | ||||
self.sa.add(lfsstore) | ||||
r1738 | # enable hgevolve disabled by default | |||
hgevolve = RhodeCodeUi() | ||||
hgevolve.ui_section = 'extensions' | ||||
hgevolve.ui_key = 'evolve' | ||||
hgevolve.ui_value = '' | ||||
hgevolve.ui_active = False | ||||
self.sa.add(hgevolve) | ||||
r3625 | hgevolve = RhodeCodeUi() | |||
hgevolve.ui_section = 'experimental' | ||||
hgevolve.ui_key = 'evolution' | ||||
hgevolve.ui_value = '' | ||||
hgevolve.ui_active = False | ||||
self.sa.add(hgevolve) | ||||
hgevolve = RhodeCodeUi() | ||||
hgevolve.ui_section = 'experimental' | ||||
hgevolve.ui_key = 'evolution.exchange' | ||||
hgevolve.ui_value = '' | ||||
hgevolve.ui_active = False | ||||
self.sa.add(hgevolve) | ||||
hgevolve = RhodeCodeUi() | ||||
hgevolve.ui_section = 'extensions' | ||||
hgevolve.ui_key = 'topic' | ||||
hgevolve.ui_value = '' | ||||
hgevolve.ui_active = False | ||||
self.sa.add(hgevolve) | ||||
r1 | # enable hggit disabled by default | |||
hggit = RhodeCodeUi() | ||||
hggit.ui_section = 'extensions' | ||||
hggit.ui_key = 'hggit' | ||||
hggit.ui_value = '' | ||||
hggit.ui_active = False | ||||
self.sa.add(hggit) | ||||
# set svn branch defaults | ||||
branches = ["/branches/*", "/trunk"] | ||||
tags = ["/tags/*"] | ||||
for branch in branches: | ||||
settings_model.create_ui_section_value( | ||||
RhodeCodeUi.SVN_BRANCH_ID, branch) | ||||
for tag in tags: | ||||
settings_model.create_ui_section_value(RhodeCodeUi.SVN_TAG_ID, tag) | ||||
def create_auth_plugin_options(self, skip_existing=False): | ||||
""" | ||||
Create default auth plugin settings, and make it active | ||||
:param skip_existing: | ||||
""" | ||||
r4186 | defaults = [ | |||
('auth_plugins', | ||||
'egg:rhodecode-enterprise-ce#token,egg:rhodecode-enterprise-ce#rhodecode', | ||||
'list'), | ||||
r1 | ||||
r4186 | ('auth_authtoken_enabled', | |||
'True', | ||||
'bool'), | ||||
('auth_rhodecode_enabled', | ||||
'True', | ||||
'bool'), | ||||
] | ||||
for k, v, t in defaults: | ||||
r1 | if (skip_existing and | |||
SettingsModel().get_setting_by_name(k) is not None): | ||||
r3061 | log.debug('Skipping option %s', k) | |||
r1 | continue | |||
setting = RhodeCodeSetting(k, v, t) | ||||
self.sa.add(setting) | ||||
def create_default_options(self, skip_existing=False): | ||||
"""Creates default settings""" | ||||
for k, v, t in [ | ||||
('default_repo_enable_locking', False, 'bool'), | ||||
('default_repo_enable_downloads', False, 'bool'), | ||||
('default_repo_enable_statistics', False, 'bool'), | ||||
('default_repo_private', False, 'bool'), | ||||
('default_repo_type', 'hg', 'unicode')]: | ||||
if (skip_existing and | ||||
SettingsModel().get_setting_by_name(k) is not None): | ||||
r3061 | log.debug('Skipping option %s', k) | |||
r1 | continue | |||
setting = RhodeCodeSetting(k, v, t) | ||||
self.sa.add(setting) | ||||
def fixup_groups(self): | ||||
def_usr = User.get_default_user() | ||||
for g in RepoGroup.query().all(): | ||||
g.group_name = g.get_new_name(g.name) | ||||
self.sa.add(g) | ||||
# get default perm | ||||
default = UserRepoGroupToPerm.query()\ | ||||
.filter(UserRepoGroupToPerm.group == g)\ | ||||
.filter(UserRepoGroupToPerm.user == def_usr)\ | ||||
.scalar() | ||||
if default is None: | ||||
r3061 | log.debug('missing default permission for group %s adding', g) | |||
r1 | perm_obj = RepoGroupModel()._create_default_perms(g) | |||
self.sa.add(perm_obj) | ||||
def reset_permissions(self, username): | ||||
""" | ||||
Resets permissions to default state, useful when old systems had | ||||
bad permissions, we must clean them up | ||||
:param username: | ||||
""" | ||||
default_user = User.get_by_username(username) | ||||
if not default_user: | ||||
return | ||||
u2p = UserToPerm.query()\ | ||||
.filter(UserToPerm.user == default_user).all() | ||||
fixed = False | ||||
if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS): | ||||
for p in u2p: | ||||
Session().delete(p) | ||||
fixed = True | ||||
self.populate_default_permissions() | ||||
return fixed | ||||
def config_prompt(self, test_repo_path='', retries=3): | ||||
defaults = self.cli_args | ||||
_path = defaults.get('repos_location') | ||||
if retries == 3: | ||||
log.info('Setting up repositories config') | ||||
if _path is not None: | ||||
path = _path | ||||
elif not self.tests and not test_repo_path: | ||||
r5148 | path = input( | |||
r1 | 'Enter a valid absolute path to store repositories. ' | |||
'All repositories in that path will be added automatically:' | ||||
r5148 | ) | |||
r1 | else: | |||
path = test_repo_path | ||||
path_ok = True | ||||
# check proper dir | ||||
if not os.path.isdir(path): | ||||
path_ok = False | ||||
r3061 | log.error('Given path %s is not a valid directory', path) | |||
r1 | ||||
elif not os.path.isabs(path): | ||||
path_ok = False | ||||
r3061 | log.error('Given path %s is not an absolute path', path) | |||
r1 | ||||
# check if path is at least readable. | ||||
if not os.access(path, os.R_OK): | ||||
path_ok = False | ||||
r3061 | log.error('Given path %s is not readable', path) | |||
r1 | ||||
# check write access, warn user about non writeable paths | ||||
elif not os.access(path, os.W_OK) and path_ok: | ||||
r3061 | log.warning('No write permission to given path %s', path) | |||
r1 | ||||
r5085 | q = (f'Given path {path} is not writeable, do you want to ' | |||
f'continue with read only mode ? [y/n]') | ||||
r270 | if not self.ask_ok(q): | |||
r1 | log.error('Canceled by user') | |||
sys.exit(-1) | ||||
if retries == 0: | ||||
sys.exit('max retries reached') | ||||
if not path_ok: | ||||
retries -= 1 | ||||
return self.config_prompt(test_repo_path, retries) | ||||
real_path = os.path.normpath(os.path.realpath(path)) | ||||
if real_path != os.path.normpath(path): | ||||
r5085 | q = (f'Path looks like a symlink, RhodeCode Enterprise will store ' | |||
f'given path as {real_path} ? [y/n]') | ||||
r1 | if not self.ask_ok(q): | |||
log.error('Canceled by user') | ||||
sys.exit(-1) | ||||
return real_path | ||||
def create_settings(self, path): | ||||
self.create_ui_settings(path) | ||||
ui_config = [ | ||||
('web', 'allow_archive', 'gz zip bz2'), | ||||
('web', 'allow_push', '*'), | ||||
('web', 'baseurl', '/'), | ||||
('paths', '/', path), | ||||
r1568 | ('phases', 'publish', 'True') | |||
r1 | ] | |||
for section, key, value in ui_config: | ||||
ui_conf = RhodeCodeUi() | ||||
setattr(ui_conf, 'ui_section', section) | ||||
setattr(ui_conf, 'ui_key', key) | ||||
setattr(ui_conf, 'ui_value', value) | ||||
self.sa.add(ui_conf) | ||||
# rhodecode app settings | ||||
settings = [ | ||||
('realm', 'RhodeCode', 'unicode'), | ||||
('title', '', 'unicode'), | ||||
('pre_code', '', 'unicode'), | ||||
('post_code', '', 'unicode'), | ||||
r4186 | ||||
# Visual | ||||
r1 | ('show_public_icon', True, 'bool'), | |||
('show_private_icon', True, 'bool'), | ||||
r4637 | ('stylify_metatags', True, 'bool'), | |||
r1 | ('dashboard_items', 100, 'int'), | |||
('admin_grid_items', 25, 'int'), | ||||
r4186 | ||||
('markup_renderer', 'markdown', 'unicode'), | ||||
r4637 | ('repository_fields', True, 'bool'), | |||
r1 | ('show_version', True, 'bool'), | |||
r4186 | ('show_revision_number', True, 'bool'), | |||
('show_sha_length', 12, 'int'), | ||||
r1 | ('use_gravatar', False, 'bool'), | |||
('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'), | ||||
r4186 | ||||
r1 | ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'), | |||
r4629 | ('clone_uri_id_tmpl', Repository.DEFAULT_CLONE_URI_ID, 'unicode'), | |||
r4186 | ('clone_uri_ssh_tmpl', Repository.DEFAULT_CLONE_URI_SSH, 'unicode'), | |||
r1 | ('support_url', '', 'unicode'), | |||
('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'), | ||||
r4186 | ||||
# VCS Settings | ||||
('pr_merge_enabled', True, 'bool'), | ||||
('use_outdated_comments', True, 'bool'), | ||||
('diff_cache', True, 'bool'), | ||||
r1 | ] | |||
for key, val, type_ in settings: | ||||
sett = RhodeCodeSetting(key, val, type_) | ||||
self.sa.add(sett) | ||||
self.create_auth_plugin_options() | ||||
self.create_default_options() | ||||
log.info('created ui config') | ||||
def create_user(self, username, password, email='', admin=False, | ||||
strict_creation_check=True, api_key=None): | ||||
r3061 | log.info('creating user `%s`', username) | |||
r1 | user = UserModel().create_or_update( | |||
r4973 | username, password, email, firstname='RhodeCode', lastname='Admin', | |||
r1 | active=True, admin=admin, extern_type="rhodecode", | |||
strict_creation_check=strict_creation_check) | ||||
if api_key: | ||||
r2951 | log.info('setting a new default auth token for user `%s`', username) | |||
UserModel().add_auth_token( | ||||
user=user, lifetime_minutes=-1, | ||||
role=UserModel.auth_token_role.ROLE_ALL, | ||||
r4973 | description='BUILTIN TOKEN') | |||
r1 | ||||
def create_default_user(self): | ||||
log.info('creating default user') | ||||
# create default user for handling default permissions. | ||||
user = UserModel().create_or_update(username=User.DEFAULT_USER, | ||||
password=str(uuid.uuid1())[:20], | ||||
email=User.DEFAULT_USER_EMAIL, | ||||
r4973 | firstname='Anonymous', | |||
lastname='User', | ||||
r1 | strict_creation_check=False) | |||
r2951 | # based on configuration options activate/de-activate this user which | |||
r4973 | # controls anonymous access | |||
r1 | if self.cli_args.get('public_access') is False: | |||
log.info('Public access disabled') | ||||
user.active = False | ||||
Session().add(user) | ||||
Session().commit() | ||||
def create_permissions(self): | ||||
""" | ||||
Creates all permissions defined in the system | ||||
""" | ||||
# module.(access|create|change|delete)_[name] | ||||
# module.(none|read|write|admin) | ||||
log.info('creating permissions') | ||||
PermissionModel(self.sa).create_permissions() | ||||
def populate_default_permissions(self): | ||||
""" | ||||
Populate default permissions. It will create only the default | ||||
permissions that are missing, and not alter already defined ones | ||||
""" | ||||
log.info('creating default user permissions') | ||||
PermissionModel(self.sa).create_default_user_permissions(user=User.DEFAULT_USER) | ||||