def test_existing(self): util.create_file(self.path, 'Some content') self.assertEqual('Some content', util.read_file(self.path)) with util.AtomicFile(self.path) as f: f.write('Some new content') self.assertEqual(True, f.closed) self.assertEqual('Some new content', util.read_file(self.path))
def test_existing(self): util.create_file(self.path, 'Some content') self.assertEqual('Some content', util.read_file(self.path)) with util.AtomicFile(self.path) as f: f.write('Some new content') self.assertTrue(f.closed) self.assertEqual('Some new content', util.read_file(self.path))
def test_existing(self): util.create_file(self.path, 'Some content') self.assertEqual('Some content', util.read_file(self.path)) f = util.AtomicFile(self.path) try: f.write('Some new content') finally: f.close() self.assertEqual('Some new content', util.read_file(self.path))
def test_existing_open_for_reading(self): util.create_file(self.path, 'Initial file content') self.assertEqual('Initial file content', util.read_file(self.path)) with open(self.path) as rf: with util.AtomicFile(self.path) as f: f.write('Replaced content') self.assertEqual(True, rf.closed) self.assertEqual(True, f.closed) self.assertEqual('Replaced content', util.read_file(self.path))
def test_symbolic_link(self): link_path = os.path.join(self.dir, 'trac-tempfile-link') os.symlink(self.path, link_path) with util.AtomicFile(link_path) as f: f.write('test content') self.assertTrue(os.path.islink(link_path)) self.assertEqual('test content', util.read_file(link_path)) self.assertEqual('test content', util.read_file(self.path))
def test_existing_open_for_reading(self): util.create_file(self.path, 'Initial file content') self.assertEqual('Initial file content', util.read_file(self.path)) rf = open(self.path) try: f = util.AtomicFile(self.path) try: f.write('Replaced content') finally: f.close() finally: rf.close() self.assertEqual('Replaced content', util.read_file(self.path))
def _get_authz_info(self): if not self.authz_file: self.log.error("The [svn] authz_file configuration option in " "trac.ini is empty or not defined") raise ConfigurationError() try: mtime = os.path.getmtime(self.authz_file) except OSError as e: self.log.error( "Error accessing svn authz permission policy " "file: %s", exception_to_unicode(e)) raise ConfigurationError() if mtime != self._mtime: self._mtime = mtime rm = RepositoryManager(self.env) modules = set(repos.reponame for repos in rm.get_real_repositories()) if '' in modules and self.authz_module_name: modules.add(self.authz_module_name) modules.add('') self.log.info('Parsing authz file: %s', self.authz_file) try: self._authz = parse(read_file(self.authz_file), modules) except Exception as e: self.log.error( "Error parsing svn authz permission policy " "file: %s", exception_to_unicode(e)) raise ConfigurationError() else: self._users = set(user for paths in self._authz.itervalues() for path in paths.itervalues() for user, result in path.iteritems() if result) return self._authz, self._users
def _test_convert_with_plugin_to_sqlite_env(self): self.src_env = Environment(self.src_path) self.assertTrue(self.src_env.needs_upgrade()) self.src_env.upgrade() self.assertFalse(self.src_env.needs_upgrade()) src_options = self._get_options(self.src_env) src_records = self._get_all_records(self.src_env) self._convert_db(self.src_env, 'sqlite:db/trac.db', self.dst_path) self.dst_env = Environment(self.dst_path) self.assertFalse(self.dst_env.needs_upgrade()) self.assertFalse( os.path.exists(os.path.join(self.dst_env.log_dir, 'created'))) self.assertTrue( os.path.exists(os.path.join(self.dst_env.log_dir, 'upgraded'))) dst_options = self._get_options(self.dst_env) dst_records = self._get_all_records(self.dst_env) self.assertEqual({ 'name': 'initial_database_version', 'value': '21' }, dst_records['system']['initial_database_version']) self._compare_records(src_records, dst_records) self.assertEqual(src_options, dst_options) att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt') self.assertEqual('test', read_file(att.path))
def import_page(self, filename, title, create_only=[], replace=False): if filename: if not os.path.isfile(filename): raise AdminCommandError( _("'%(name)s' is not a file", name=path_to_unicode(filename))) data = read_file(filename) else: data = sys.stdin.read() data = to_unicode(data, 'utf-8') name = unicode_unquote(title.encode('utf-8')) page = model.WikiPage(self.env, name) if page.exists: if name in create_only: self.log.info("%s already exists", name) return False if data == page.text: self.log.info("%s is already up to date", name) return False page.text = data try: page.save('trac', None, replace=replace) except TracError as e: raise AdminCommandError(e) self.log.info("%s imported from %s", name, path_to_unicode(filename)) return True
def test_non_existing(self): f = util.AtomicFile(self.path) try: f.write('test content') finally: f.close() self.assertEqual('test content', util.read_file(self.path))
def _get_authz_info(self): try: mtime = os.path.getmtime(self.authz_file) except OSError as e: if self._authz is not None: self.log.error('Error accessing authz file: %s', exception_to_unicode(e)) self._mtime = mtime = 0 self._authz = None self._users = set() if mtime != self._mtime: self._mtime = mtime rm = RepositoryManager(self.env) modules = set(repos.reponame for repos in rm.get_real_repositories()) if '' in modules and self.authz_module_name: modules.add(self.authz_module_name) modules.add('') self.log.info('Parsing authz file: %s', self.authz_file) try: self._authz = parse(read_file(self.authz_file), modules) self._users = set(user for paths in self._authz.itervalues() for path in paths.itervalues() for user, result in path.iteritems() if result) except Exception as e: self._authz = None self._users = set() self.log.error('Error parsing authz file: %s', exception_to_unicode(e)) return self._authz, self._users
def _test_unicode_path(self): self.path = os.path.join(tempfile.gettempdir(), u'träc-témpfilè') f = util.AtomicFile(self.path) try: f.write('test content') finally: f.close() self.assertEqual('test content', util.read_file(self.path))
def verify(self): """Verify that the provided path points to a valid Trac environment directory.""" try: tag = read_file(os.path.join(self.path, "VERSION")).splitlines()[0] if tag != _VERSION: raise Exception(_("Unknown Trac environment type '%(type)s'", type=tag)) except Exception as e: raise TracError(_("No Trac environment found at %(path)s\n" "%(e)s", path=self.path, e=e))
def get_tracignore_patterns(env_parent_dir): """Return the list of patterns from env_parent_dir/.tracignore or a default pattern of `".*"` if the file doesn't exist. """ path = os.path.join(env_parent_dir, '.tracignore') try: lines = [line.strip() for line in read_file(path).splitlines()] except IOError: return ['.*'] return [line for line in lines if line and not line.startswith('#')]
def verify(self): """Verify that the provided path points to a valid Trac environment directory.""" try: tag = read_file(os.path.join(self.path, 'VERSION')).splitlines()[0] if tag != _VERSION: raise Exception("Unknown Trac environment type '%s'" % tag) except Exception as e: raise TracError("No Trac environment found at %s\n%s" % (self.path, e))
def verify(self): """Verify that the provided path points to a valid Trac environment directory.""" try: tag = read_file(os.path.join(self.path, 'VERSION')).splitlines()[0] if tag != _VERSION: raise Exception(_("Unknown Trac environment type '%(type)s'", type=tag)) except Exception as e: raise TracError(_("No Trac environment found at %(path)s\n" "%(e)s", path=self.path, e=e))
def test_set_and_save_inherit_remove_matching(self): """Options with values matching the inherited value are removed from the base configuration. """ with self.inherited_file(): self._write(['[a]', u'ôption = x'], site=True) config = self._read() self.assertEqual('x', config.get('a', u'ôption')) config.save() self.assertEqual( '# -*- coding: utf-8 -*-\n' '\n' '[inherit]\n' 'file = trac-site.ini\n' '\n', read_file(self.filename)) config.set('a', u'ôption', 'y') config.save() self.assertEqual( '# -*- coding: utf-8 -*-\n' '\n' '[a]\n' 'ôption = y\n' '\n' '[inherit]\n' 'file = trac-site.ini\n' '\n', read_file(self.filename)) config.set('a', u'ôption', 'x') config.save() self.assertEqual( '# -*- coding: utf-8 -*-\n' '\n' '[inherit]\n' 'file = trac-site.ini\n' '\n', read_file(self.filename))
def setUp(self, port=None): """If no port is specified, use a semi-random port and subdirectory 'testenv'; but if a port is specified, use that port and subdirectory 'testenv<portnum>'. """ if port is None: try: port = int(os.getenv('TRAC_TEST_PORT')) except (TypeError, ValueError): pass env_path = os.getenv('TRAC_TEST_ENV_PATH') if not env_path: env_name = 'testenv%s' % (port or '') env_path = os.path.join(trac_source_tree, env_name) else: env_path += str(port or '') if port is None: port = get_ephemeral_port() server_port = get_ephemeral_port() baseurl = "http://127.0.0.1:%s" % port self._testenv = self.env_class(env_path, server_port, baseurl) self._testenv.set_config('project', 'name', 'Functional Tests') self._testenv.set_config('trac', 'base_url', baseurl) create_file( os.path.join(env_path, 'trac', 'htdocs', 'your_project_logo.png'), read_file(os.path.join(trac_source_tree, 'trac', 'htdocs', 'trac_logo_mini.png'), 'rb'), 'wb') # functional-testing.log gets the twill output self.functional_test_log = \ os.path.join(env_path, 'functional-testing.log') tc.init(port, server_port) self._testenv.start() try: self._tester = self.tester_class(baseurl) except: self._testenv.stop() tc.close() raise self.fixture = (self._testenv, self._tester) atexit.register(self.tearDown)
def import_page(self, filename, title, create_only=[], replace=False): if not validate_page_name(title): raise AdminCommandError( _("Invalid Wiki page name '%(name)s'", name=title)) if filename: if not os.path.isfile(filename): raise AdminCommandError( _("'%(name)s' is not a file", name=path_to_unicode(filename))) data = read_file(filename) else: data = sys.stdin.read() data = to_unicode(data, 'utf-8') with self.env.db_transaction as db: # Make sure we don't insert the exact same page twice old = db( """SELECT text FROM wiki WHERE name=%s ORDER BY version DESC LIMIT 1 """, (title, )) if old and title in create_only: printout(_(" %(title)s already exists", title=title)) return False if old and data == old[0][0]: printout(_(" %(title)s is already up to date", title=title)) return False if replace and old: db( """UPDATE wiki SET text=%s WHERE name=%s AND version=(SELECT max(version) FROM wiki WHERE name=%s) """, (data, title, title)) else: db( """INSERT INTO wiki (version, readonly, name, time, author, text) SELECT 1 + COALESCE(max(version), 0), COALESCE(max(readonly), 0), %s, %s, 'trac', %s FROM wiki WHERE name=%s AND version=(SELECT max(version) FROM wiki WHERE name=%s) """, (title, to_utimestamp( datetime_now(utc)), data, title, title)) if not old: del WikiSystem(self.env).pages return True
def import_page(self, filename, title, create_only=[], replace=False): if filename: if not os.path.isfile(filename): raise AdminCommandError(_("'%(name)s' is not a file", name=filename)) data = read_file(filename) else: data = sys.stdin.read() data = to_unicode(data, 'utf-8') result = [True] @self.env.with_transaction() def do_import(db): cursor = db.cursor() # Make sure we don't insert the exact same page twice cursor.execute("SELECT text FROM wiki WHERE name=%s " "ORDER BY version DESC LIMIT 1", (title,)) old = list(cursor) if old and title in create_only: printout(_(' %(title)s already exists', title=title)) result[0] = False return if old and data == old[0][0]: printout(_(' %(title)s is already up to date', title=title)) result[0] = False return if replace and old: cursor.execute("UPDATE wiki SET text=%s WHERE name=%s " " AND version=(SELECT max(version) FROM wiki " " WHERE name=%s)", (data, title, title)) else: cursor.execute("INSERT INTO wiki(version,name,time,author," " ipnr,text) " "SELECT 1+COALESCE(max(version),0),%s,%s," " 'trac','127.0.0.1',%s FROM wiki " "WHERE name=%s", (title, to_utimestamp(datetime.now(utc)), data, title)) if not old: del WikiSystem(self.env).pages return result[0]
def test_migrate_to_sqlite_env(self): dburi = get_dburi() if dburi == 'sqlite::memory:': dburi = 'sqlite:db/trac.db' self._create_env(self.src_path, dburi) self.src_env = Environment(self.src_path) src_options = self._get_options(self.src_env) src_records = self._get_all_records(self.src_env) self._migrate(self.src_env, self.dst_path, 'sqlite:db/trac.db') self.dst_env = Environment(self.dst_path) dst_options = self._get_options(self.dst_env) dst_records = self._get_all_records(self.dst_env) self.assertEqual({'name': 'initial_database_version', 'value': '21'}, dst_records['system']['initial_database_version']) self._compare_records(src_records, dst_records) self.assertEqual(src_options, dst_options) att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt') self.assertEqual('test', read_file(att.path))
def test_convert_to_sqlite_env(self): dburi = get_dburi() if dburi == 'sqlite::memory:': dburi = 'sqlite:db/trac.db' self._create_env(self.src_path, dburi) self.src_env = Environment(self.src_path) src_options = self._get_options(self.src_env) src_records = self._get_all_records(self.src_env) self._convert_db(self.src_env, 'sqlite:db/trac.db', self.dst_path) self.dst_env = Environment(self.dst_path) dst_options = self._get_options(self.dst_env) dst_records = self._get_all_records(self.dst_env) self.assertEqual({'name': 'initial_database_version', 'value': '21'}, dst_records['system']['initial_database_version']) self._compare_records(src_records, dst_records) self.assertEqual(src_options, dst_options) att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt') self.assertEqual('test', read_file(att.path))
def import_page(self, filename, title, create_only=[], replace=False): if not validate_page_name(title): raise AdminCommandError(_("Invalid Wiki page name '%(name)s'", name=title)) if filename: if not os.path.isfile(filename): raise AdminCommandError(_("'%(name)s' is not a file", name=path_to_unicode(filename))) data = read_file(filename) else: data = sys.stdin.read() data = to_unicode(data, 'utf-8') with self.env.db_transaction as db: # Make sure we don't insert the exact same page twice old = db("""SELECT text FROM wiki WHERE name=%s ORDER BY version DESC LIMIT 1 """, (title,)) if old and title in create_only: printout(_(" %(title)s already exists", title=title)) return False if old and data == old[0][0]: printout(_(" %(title)s is already up to date", title=title)) return False if replace and old: db("""UPDATE wiki SET text=%s WHERE name=%s AND version=(SELECT max(version) FROM wiki WHERE name=%s) """, (data, title, title)) else: db("""INSERT INTO wiki(version, name, time, author, ipnr, text) SELECT 1 + COALESCE(max(version), 0), %s, %s, 'trac', '127.0.0.1', %s FROM wiki WHERE name=%s """, (title, to_utimestamp(datetime.now(utc)), data, title)) if not old: del WikiSystem(self.env).pages return True
def test_deploy(self): dest_path = mkdtemp() shebang = ('#!' + sys.executable).encode('utf-8') try: rv, output = self.execute('deploy %s' % dest_path) self.assertEqual(0, rv, output) self.assertTrue( os.path.isfile( os.path.join(dest_path, 'htdocs', 'common', 'js', 'trac.js'))) self.assertTrue( os.path.isfile( os.path.join(dest_path, 'htdocs', 'common', 'css', 'trac.css'))) for ext in ('cgi', 'fcgi', 'wsgi'): content = read_file( os.path.join(dest_path, 'cgi-bin', 'trac.%s' % ext), 'rb') self.assertIn(shebang, content) self.assertEqual(0, content.index(shebang)) self.assertIn(repr(self.env.path).encode('ascii'), content) finally: rmtree(dest_path)
def test_deploy(self): target = os.path.join(self.env.path, 'www') shebang = ('#!' + sys.executable).encode('utf-8') rv, output = self.execute('deploy %s' % target) self.assertEqual(0, rv, output) self.assertExpectedResult(output) self.assertTrue(os.path.exists(os.path.join(target, 'cgi-bin'))) self.assertTrue(os.path.exists(os.path.join(target, 'htdocs'))) self.assertTrue(os.path.exists(os.path.join(target, 'htdocs', 'common'))) self.assertTrue(os.path.exists(os.path.join(target, 'htdocs', 'site'))) self.assertTrue(os.path.isfile(os.path.join( target, 'htdocs', 'common', 'js', 'trac.js'))) self.assertTrue(os.path.isfile(os.path.join( target, 'htdocs', 'common', 'css', 'trac.css'))) for ext in ('cgi', 'fcgi', 'wsgi'): content = read_file(os.path.join(target, 'cgi-bin', 'trac.%s' % ext), 'rb') self.assertIn(shebang, content) self.assertEqual(0, content.index(shebang)) self.assertIn(repr(self.env.path).encode('ascii'), content)
def _test_migrate_with_plugin_to_sqlite_env(self): self.src_env = Environment(self.src_path) self.assertTrue(self.src_env.needs_upgrade()) self.src_env.upgrade() self.assertFalse(self.src_env.needs_upgrade()) src_options = self._get_options(self.src_env) src_records = self._get_all_records(self.src_env) self._migrate(self.src_env, self.dst_path, 'sqlite:db/trac.db') self.dst_env = Environment(self.dst_path) self.assertFalse(self.dst_env.needs_upgrade()) self.assertFalse(os.path.exists(os.path.join(self.dst_path, 'log', 'created'))) self.assertTrue(os.path.exists(os.path.join(self.dst_path, 'log', 'upgraded'))) dst_options = self._get_options(self.dst_env) dst_records = self._get_all_records(self.dst_env) self.assertEqual({'name': 'initial_database_version', 'value': '21'}, dst_records['system']['initial_database_version']) self._compare_records(src_records, dst_records) self.assertEqual(src_options, dst_options) att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt') self.assertEqual('test', read_file(att.path))
def _read(filename): return read_file(filename).decode('utf-8')
def _test_unicode_path(self): self.path = os.path.join(tempfile.gettempdir(), u'träc-témpfilè') with util.AtomicFile(self.path) as f: f.write('test content') self.assertEqual(True, f.closed) self.assertEqual('test content', util.read_file(self.path))
def test_create_and_read_file(self): util.create_file(self.filename, self.data, 'wb') with open(self.filename, 'rb') as f: self.assertEqual(self.data, f.read()) self.assertEqual(self.data, util.read_file(self.filename, 'rb'))
class AuthzSourcePolicy(Component): """Permission policy for `source:` and `changeset:` resources using a Subversion authz file. `FILE_VIEW` and `BROWSER_VIEW` permissions are granted as specified in the authz file. `CHANGESET_VIEW` permission is granted for changesets where `FILE_VIEW` is granted on at least one modified file, as well as for empty changesets. """ implements(IPermissionPolicy) authz_file = PathOption( 'trac', 'authz_file', '', """The path to the Subversion [http://svnbook.red-bean.com/en/1.5/svn.serverconfig.pathbasedauthz.html authorization (authz) file]. To enable authz permission checking, the `AuthzSourcePolicy` permission policy must be added to `[trac] permission_policies`. """) authz_module_name = Option( 'trac', 'authz_module_name', '', """The module prefix used in the `authz_file` for the default repository. If left empty, the global section is used. """) _mtime = 0 _authz = {} _users = set() _handled_perms = frozenset([(None, 'BROWSER_VIEW'), (None, 'CHANGESET_VIEW'), (None, 'FILE_VIEW'), (None, 'LOG_VIEW'), ('source', 'BROWSER_VIEW'), ('source', 'FILE_VIEW'), ('source', 'LOG_VIEW'), ('changeset', 'CHANGESET_VIEW')]) # IPermissionPolicy methods def check_permission(self, action, username, resource, perm): realm = resource.realm if resource else None if (realm, action) in self._handled_perms: authz, users = self._get_authz_info() if authz is None: return False if username == 'anonymous': usernames = ('$anonymous', '*') else: usernames = (username, '$authenticated', '*') if resource is None: return True if users & set(usernames) else None rm = RepositoryManager(self.env) try: repos = rm.get_repository(resource.parent.id) except TracError: return True # Allow error to be displayed in the repo index if repos is None: return True modules = [resource.parent.id or self.authz_module_name] if modules[0]: modules.append('') def check_path(path): path = '/' + join(repos.scope, path) if path != '/': path += '/' # Allow access to parent directories of allowed resources if any( section.get(user) is True for module in modules for spath, section in authz.get( module, {}).iteritems() if spath.startswith(path) for user in usernames): return True # Walk from resource up parent directories for spath in parent_iter(path): for module in modules: section = authz.get(module, {}).get(spath) if section: for user in usernames: result = section.get(user) if result is not None: return result if realm == 'source': return check_path(resource.id) elif realm == 'changeset': changes = list(repos.get_changeset(resource.id).get_changes()) if not changes or any( check_path(change[0]) for change in changes): return True def _get_authz_info(self): try: mtime = os.path.getmtime(self.authz_file) except OSError, e: if self._authz is not None: self.log.error('Error accessing authz file: %s', exception_to_unicode(e)) self._mtime = mtime = 0 self._authz = None self._users = set() if mtime > self._mtime: self._mtime = mtime rm = RepositoryManager(self.env) modules = set(repos.reponame for repos in rm.get_real_repositories()) if '' in modules and self.authz_module_name: modules.add(self.authz_module_name) modules.add('') self.log.info('Parsing authz file: %s' % self.authz_file) try: self._authz = parse(read_file(self.authz_file), modules) self._users = set(user for paths in self._authz.itervalues() for path in paths.itervalues() for user, result in path.iteritems() if result) except Exception, e: self._authz = None self._users = set() self.log.error('Error parsing authz file: %s', exception_to_unicode(e))
def test_non_existing(self): with util.AtomicFile(self.path) as f: f.write('test content') self.assertEqual(True, f.closed) self.assertEqual('test content', util.read_file(self.path))