mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
WIP
This commit is contained in:
parent
e1d74d8582
commit
c691323999
@ -3,3 +3,4 @@
|
||||
from . import frontend
|
||||
from . import hook
|
||||
from . import badge
|
||||
from . import jsonroutes
|
||||
|
118
runbot/controllers/jsonroutes.py
Normal file
118
runbot/controllers/jsonroutes.py
Normal file
@ -0,0 +1,118 @@
|
||||
import json
|
||||
|
||||
from functools import wraps
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.http import Controller, request, route
|
||||
from odoo.osv import expression
|
||||
|
||||
RECORDS_PER_PAGE = 100
|
||||
|
||||
def to_json(fn):
|
||||
@wraps(fn)
|
||||
def decorator(*args, **kwargs):
|
||||
headers = [('Content-Type', 'application/json'),
|
||||
('Cache-Control', 'no-store')]
|
||||
try:
|
||||
return request.make_response(json.dumps(fn(*args, **kwargs)._get_description(), indent=4, default=str), headers)
|
||||
except AccessError:
|
||||
response = request.make_response(json.dumps('unauthorized'), headers)
|
||||
response.status = 403
|
||||
return response
|
||||
return decorator
|
||||
|
||||
class RunbotJsonRoutes(Controller):
|
||||
|
||||
@route(['/runbot/json/projects',
|
||||
'/runbot/json/projects/<int:project_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def projects(self, project_id=None, **kwargs):
|
||||
if project_id:
|
||||
projects = request.env['runbot.project'].browse(project_id)
|
||||
else:
|
||||
domain = ([('group_ids', '=', False)]) if request.env.user._is_public() else []
|
||||
projects = request.env['runbot.project'].search(domain)
|
||||
return projects
|
||||
|
||||
@route(['/runbot/json/bundles/<int:bundle_id>',
|
||||
'/runbot/json/projects/<int:project_id>/bundles'], type='http', auth='public')
|
||||
@to_json
|
||||
def bundles(self, project_id=None, bundle_id=None, page=0, **kwargs):
|
||||
offset = int(page) * RECORDS_PER_PAGE
|
||||
domain = []
|
||||
if bundle_id:
|
||||
bundles = request.env['runbot.bundle'].browse(bundle_id)
|
||||
else:
|
||||
domain = [('project_id', '=', project_id)]
|
||||
if 'sticky' in kwargs:
|
||||
domain = expression.AND([domain, [('sticky', '=', kwargs['sticky'])]])
|
||||
if 'name' in kwargs:
|
||||
name_query = kwargs['name']
|
||||
name_query = name_query if len(name_query) < 60 else name_query[:60]
|
||||
domain = expression.AND([domain, [('name', 'ilike', name_query)]])
|
||||
bundles = request.env['runbot.bundle'].search(domain, order='id desc', limit=RECORDS_PER_PAGE, offset=offset)
|
||||
return bundles
|
||||
|
||||
@route(['/runbot/json/bundles/<int:bundle_id>/batches',
|
||||
'/runbot/json/batches/<int:batch_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def batches(self, bundle_id=None, batch_id=None, page=0, **kwargs):
|
||||
offset = int(page) * RECORDS_PER_PAGE
|
||||
if batch_id:
|
||||
batches = request.env['runbot.batch'].browse(batch_id)
|
||||
else:
|
||||
domain = [('bundle_id', '=', bundle_id)] if bundle_id else []
|
||||
domain += [('state', '=', kwargs['state'])] if 'state' in kwargs else []
|
||||
batches = request.env['runbot.batch'].search(domain, order="id desc", limit=RECORDS_PER_PAGE, offset=offset)
|
||||
return batches
|
||||
|
||||
@route(['/runbot/json/batches/<int:batch_id>/commits',
|
||||
'/runbot/json/commits/<int:commit_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def commits(self, commit_id=None, batch_id=None, page=0, **kwargs):
|
||||
if commit_id:
|
||||
commits = request.env['runbot.commit'].browse(commit_id)
|
||||
else:
|
||||
commits = request.env['runbot.batch'].browse(batch_id).commit_ids
|
||||
return commits
|
||||
|
||||
@route(['/runbot/json/commits/<int:commit_id>/commit_links',
|
||||
'/runbot/json/commit_links/<int:commit_link_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def commit_links(self, commit_id=None, commit_link_id=None, page=0, **kwargs):
|
||||
if commit_link_id:
|
||||
commit_links = request.env['runbot.commit.link'].browse(commit_link_id)
|
||||
else:
|
||||
domain = [('commit_id', '=', commit_id)]
|
||||
commit_links = request.env['runbot.commit.link'].search(domain)
|
||||
return commit_links
|
||||
|
||||
@route(['/runbot/json/repos',
|
||||
'/runbot/json/repos/<int:repo_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def repos(self, repo_id=None, page=0, **kwargs):
|
||||
if repo_id:
|
||||
repos = request.env['runbot.repo'].browse(repo_id)
|
||||
else:
|
||||
domain = []
|
||||
repos = request.env['runbot.repo'].search(domain)
|
||||
return repos
|
||||
|
||||
@route(['/runbot/json/batches/<int:batch_id>/slots',
|
||||
'/runbot/json/batch_slots/<int:slot_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def batch_slots(self, batch_id=None, slot_id=None, page=0, **kwargs):
|
||||
if slot_id:
|
||||
slots = request.env['runbot.batch.slot'].browse(slot_id)
|
||||
else:
|
||||
slots = request.env['runbot.batch'].browse(batch_id).slot_ids
|
||||
return slots
|
||||
|
||||
@route(['/runbot/json/batches/<int:batch_id>/builds',
|
||||
'/runbot/json/builds/<int:build_id>'], type='http', auth='public')
|
||||
@to_json
|
||||
def builds(self, build_id=None, batch_id=None, page=0, **kwargs):
|
||||
if build_id:
|
||||
builds = request.env['runbot.build'].browse(build_id)
|
||||
else:
|
||||
builds = request.env['runbot.batch'].browse(batch_id).all_build_ids
|
||||
return builds
|
@ -176,7 +176,6 @@ class Batch(models.Model):
|
||||
lambda t: not t.version_domain or \
|
||||
self.bundle_id.version_id.filtered_domain(t.get_version_domain())
|
||||
)
|
||||
|
||||
pushed_repo = self.commit_link_ids.mapped('commit_id.repo_id')
|
||||
dependency_repos = triggers.mapped('dependency_ids')
|
||||
all_repos = triggers.mapped('repo_ids') | dependency_repos
|
||||
@ -327,7 +326,6 @@ class Batch(models.Model):
|
||||
'used_custom_trigger': bool(trigger_custom),
|
||||
}
|
||||
params_value['builds_reference_ids'] = trigger._reference_builds(bundle)
|
||||
|
||||
params = self.env['runbot.build.params'].create(params_value)
|
||||
|
||||
build = self.env['runbot.build']
|
||||
@ -412,6 +410,23 @@ class Batch(models.Model):
|
||||
'level': level,
|
||||
})
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/batches/{r.id}',
|
||||
'state': r.state,
|
||||
'last_update': r.last_update,
|
||||
'bundle_name' : r.bundle_id.name,
|
||||
'bundle_url': f'{r.get_base_url()}/runbot/json/bundles/{r.bundle_id.id}',
|
||||
'commits_url': f'{r.get_base_url()}/runbot/json/batches/{r.id}/commits',
|
||||
'commits': [info for commit in r.commit_ids for info in commit._get_description()],
|
||||
'slots_url': f'{r.get_base_url()}/runbot/json/batches/{r.id}/slots',
|
||||
'slots' : [info for slot in r.slot_ids for info in slot._get_description()],
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
||||
|
||||
class BatchLog(models.Model):
|
||||
_name = 'runbot.batch.log'
|
||||
@ -467,3 +482,19 @@ class BatchSlot(models.Model):
|
||||
self.batch_id._log(f'Trigger {self.trigger_id.name} was started by {self.env.user.name}')
|
||||
self.link_type, self.build_id = self.batch_id._create_build(self.params_id)
|
||||
return self.build_id
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/batch_slots/{r.id}',
|
||||
'trigger_name': r.trigger_id.name,
|
||||
'link_type': r.link_type,
|
||||
'batch_url': f'{r.get_base_url()}/runbot/json/batches/{r.batch_id.id}',
|
||||
'build_url': f'{r.get_base_url()}/runbot/json/builds/{r.build_id.id}' if r.build_id else False,
|
||||
'active': r.active,
|
||||
'skipped': r.skipped,
|
||||
'build': r.build_id._get_description()[0] if r.build_id else False,
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
@ -1202,3 +1202,25 @@ class BuildResult(models.Model):
|
||||
|
||||
def parse_config(self):
|
||||
return set(findall(self._server("tools/config.py"), '--[\w-]+', ))
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'dest': r.dest,
|
||||
'url': f'{r.get_base_url()}/runbot/json/builds/{r.id}',
|
||||
'parent_build_url': f'{r.get_base_url()}/runbot/json/builds/{r.parent_id}' if r.parent_id else False,
|
||||
'params_url': f'{r.get_base_url()}/runbot/json/build_params/{r.params_id.id}',
|
||||
'version': r.version_id.name,
|
||||
'config': r.config_id.name,
|
||||
'trigger': r.trigger_id.name,
|
||||
'global_state': r.global_state,
|
||||
'local_state': r.local_state,
|
||||
'global_result': r.global_result,
|
||||
'local_result': r.local_result,
|
||||
'triggered_result': r.triggered_result,
|
||||
'host': r.host,
|
||||
'children': [info for child in r.children_ids for info in child._get_description()],
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
@ -246,3 +246,19 @@ class Bundle(models.Model):
|
||||
for branch in self.branch_ids.sorted(key=lambda b: (b.is_pr)):
|
||||
branch_groups[branch.remote_id.repo_id].append(branch)
|
||||
return branch_groups
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/bundles/{r.id}',
|
||||
'name': r.name,
|
||||
'sticky': r.sticky,
|
||||
'version_number': r.version_number,
|
||||
'project_url': f'{r.get_base_url()}/runbot/json/projects/{r.project_id.id}',
|
||||
'last_batch_url': f'{r.get_base_url()}/runbot/json/batches/{r.last_batch.id}',
|
||||
'last_batch' : r.last_batch._get_description()[0] if r.last_batch else False,
|
||||
'batches_url': f'{r.get_base_url()}/runbot/json/bundles/{r.id}/batches'
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
@ -153,6 +153,23 @@ class Commit(models.Model):
|
||||
'to_process': True,
|
||||
})
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/commits/{r.id}',
|
||||
'hash': r.name,
|
||||
'repo': r.repo_id.name,
|
||||
'repo_url': f'{r.get_base_url()}/runbot/json/repos/{r.repo_id.id}',
|
||||
'author': r.author,
|
||||
'author_email': r.author_email,
|
||||
'committer': r.committer,
|
||||
'committer_email': r.committer_email,
|
||||
'subject': r.subject,
|
||||
'commit_links_url': f'{r.get_base_url()}/runbot/json/commits/{r.id}/commit_links',
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
||||
class CommitLink(models.Model):
|
||||
_name = 'runbot.commit.link'
|
||||
@ -171,6 +188,30 @@ class CommitLink(models.Model):
|
||||
diff_add = fields.Integer('# line added')
|
||||
diff_remove = fields.Integer('# line removed')
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/commit_links/{r.id}',
|
||||
'commit_url': f'{r.get_base_url()}/runbot/json/commits/{r.id}',
|
||||
'hash': r.commit_id.name,
|
||||
'match_type': r.match_type,
|
||||
'author': r.commit_id.author,
|
||||
'author_email': r.commit_id.author_email,
|
||||
'committer': r.commit_id.committer,
|
||||
'committer_email': r.commit_id.committer_email,
|
||||
'subject': r.commit_id.subject,
|
||||
'base_commit': r.base_commit_id.name,
|
||||
'base_commit_url': f'{r.get_base_url()}/runbot/json/commits/{r.base_commit_id.id}' if r.base_commit_id else False,
|
||||
'merge_base_commit': r.merge_base_commit_id.name,
|
||||
'merge_base_commit_url': f'{r.get_base_url()}/runbot/json/commits/{r.merge_base_commit_id.id}' if r.merge_base_commit_id else False,
|
||||
'branch_url': f'{r.get_base_url()}/runbot/json/branches/{r.id}',
|
||||
'branch_name': r.branch_id.name,
|
||||
'github_branch_url': f'https://{r.branch_id.remote_id.base_url}/commit/{r.commit_id.name}',
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
||||
|
||||
class CommitStatus(models.Model):
|
||||
_name = 'runbot.commit.status'
|
||||
|
@ -42,6 +42,17 @@ class Project(models.Model):
|
||||
project.dummy_bundle_id = bundle
|
||||
return projects
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/projects/{r.id}',
|
||||
'name': r.name,
|
||||
'keep_sticky_running': r.keep_sticky_running,
|
||||
'bundles_url': f'{r.get_base_url()}/runbot/json/projects/{r.id}/bundles'
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
||||
class Category(models.Model):
|
||||
_name = 'runbot.category'
|
||||
|
@ -563,6 +563,22 @@ class Repo(models.Model):
|
||||
if file.startswith(base_path):
|
||||
return file[len(base_path):].strip('/').split('/')[0]
|
||||
|
||||
def _get_description(self):
|
||||
return[
|
||||
{
|
||||
'id': r.id,
|
||||
'url': f'{r.get_base_url()}/runbot/json/repos/{r.id}',
|
||||
'name': r.name,
|
||||
'project': r.project_id.name,
|
||||
'project_url': f'{r.get_base_url()}/runbot/json/projects/{r.project_id.id}',
|
||||
'hook_time': r.hook_time,
|
||||
'hook_time_string': datetime.datetime.fromtimestamp(r.hook_time),
|
||||
'last_processed_hook_time': r.last_processed_hook_time,
|
||||
'last_processed_hook_time_string': datetime.datetime.fromtimestamp(r.last_processed_hook_time),
|
||||
}
|
||||
for r in self
|
||||
]
|
||||
|
||||
|
||||
class RefTime(models.Model):
|
||||
_name = 'runbot.repo.reftime'
|
||||
|
@ -130,5 +130,35 @@
|
||||
<field name="perm_read" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="runbot_bundle_access_user" model="ir.rule">
|
||||
<field name="name">User can read bundle from public projects or specific groups</field>
|
||||
<field name="model_id" ref="model_runbot_bundle"/>
|
||||
<field name="domain_force">['|', ('project_id.group_ids.users', 'in', user.id), ('project_id.group_ids', '=', False)]</field>
|
||||
</record>
|
||||
|
||||
<record id="runbot_batch_access_user" model="ir.rule">
|
||||
<field name="name">User can read batch from public projects or specific groups</field>
|
||||
<field name="model_id" ref="model_runbot_batch"/>
|
||||
<field name="domain_force">['|', ('bundle_id.project_id.group_ids.users', 'in', user.id), ('bundle_id.project_id.group_ids', '=', False)]</field>
|
||||
</record>
|
||||
|
||||
<record id="runbot_commit_access_user" model="ir.rule">
|
||||
<field name="name">User can read commits from public projects or specific groups</field>
|
||||
<field name="model_id" ref="model_runbot_commit"/>
|
||||
<field name="domain_force">['|', ('repo_id.project_id.group_ids.users', 'in', user.id), ('repo_id.project_id.group_ids', '=', False)]</field>
|
||||
</record>
|
||||
|
||||
<record id="runbot_batch_slot_access_user" model="ir.rule">
|
||||
<field name="name">User can read batch slot from public projects or specific groups</field>
|
||||
<field name="model_id" ref="model_runbot_batch_slot"/>
|
||||
<field name="domain_force">['|', ('batch_id.bundle_id.project_id.group_ids.users', 'in', user.id), ('batch_id.bundle_id.project_id.group_ids', '=', False)]</field>
|
||||
</record>
|
||||
|
||||
<record id="runbot_build_access_user" model="ir.rule">
|
||||
<field name="name">User can read build from public projects or specific groups</field>
|
||||
<field name="model_id" ref="model_runbot_build"/>
|
||||
<field name="domain_force">['|', ('params_id.project_id.group_ids.users', 'in', user.id), ('params_id.project_id.group_ids', '=', False)]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
@ -15,3 +15,4 @@ from . import test_commit
|
||||
from . import test_upgrade
|
||||
from . import test_dockerfile
|
||||
from . import test_host
|
||||
from . import test_json_routes
|
||||
|
127
runbot/tests/test_json_routes.py
Normal file
127
runbot/tests/test_json_routes.py
Normal file
@ -0,0 +1,127 @@
|
||||
import json
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
from .common import RunbotCase
|
||||
|
||||
|
||||
class TestJsonRoutes(RunbotCase, HttpCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.additionnal_setup()
|
||||
self.private_group = self.env['res.groups'].create({
|
||||
'name': 'Test Private',
|
||||
})
|
||||
self.private_project = self.Project.create({
|
||||
'name': 'Private Test Project',
|
||||
'group_ids': [fields.Command.link(self.private_group.id)],
|
||||
})
|
||||
|
||||
self.private_repo_server = self.Repo.create({
|
||||
'name': 'private_server',
|
||||
'project_id': self.private_project.id,
|
||||
'server_files': 'server.py',
|
||||
'addons_paths': 'addons,core/addons'
|
||||
})
|
||||
|
||||
self.private_remote_server = self.Remote.create({
|
||||
'name': 'foo@example.com:base/server',
|
||||
'repo_id': self.private_repo_server.id,
|
||||
'token': '456',
|
||||
})
|
||||
|
||||
self.initial_private_server_commit = self.Commit.create({
|
||||
'name': 'afafafaf',
|
||||
'repo_id': self.private_repo_server.id,
|
||||
'date': '2020-01-01',
|
||||
'subject': 'Initial Private Commit',
|
||||
'author': 'foofoo',
|
||||
'author_email': 'foofoo@somewhere.com'
|
||||
})
|
||||
|
||||
self.private_branch_server = self.Branch.create({
|
||||
'name': '13.0',
|
||||
'remote_id': self.private_remote_server.id,
|
||||
'is_pr': False,
|
||||
'head': self.initial_private_server_commit.id,
|
||||
})
|
||||
self.branch_server.bundle_id.is_base = True
|
||||
|
||||
self.Trigger.create({
|
||||
'name': 'Private Repo Server trigger',
|
||||
'repo_ids': [(4, self.private_repo_server.id)],
|
||||
'config_id': self.default_config.id,
|
||||
'project_id': self.private_project.id,
|
||||
})
|
||||
|
||||
def check_json_route(self, route, expected_status):
|
||||
response = self.url_open(route)
|
||||
self.assertEqual(response.status_code, expected_status)
|
||||
res = json.loads(response.content)
|
||||
if expected_status == 403:
|
||||
self.assertEqual(res, 'unauthorized')
|
||||
return res
|
||||
|
||||
def test_json_flow_public_user(self):
|
||||
# test that a public user can get public project informations
|
||||
projects_infos = self.check_json_route('/runbot/json/projects', 200)
|
||||
project_names = [p['name'] for p in projects_infos]
|
||||
self.assertIn(self.project.name, project_names)
|
||||
|
||||
# test that a public user cannot get a private project informations
|
||||
self.assertNotIn('Private Project', project_names)
|
||||
self.check_json_route(f'/runbot/json/projects/{self.private_project.id}', 403)
|
||||
|
||||
bundles_infos = self.check_json_route(projects_infos[0]['bundles_url'], 200)
|
||||
bundles_names = [b['name'] for b in bundles_infos]
|
||||
self.assertIn(self.branch_server.bundle_id.name, bundles_names)
|
||||
|
||||
# check that public user cannot access private project bundles
|
||||
private_bundle = self.Bundle.search([('name', '=', '13.0'), ('project_id', '=', self.private_project.id)])
|
||||
self.check_json_route(f'/runbot/json/bundles/{private_bundle.id}', 403)
|
||||
|
||||
private_batch = self.private_branch_server.bundle_id._force()
|
||||
private_batch._prepare()
|
||||
batches_infos = self.check_json_route(f'/runbot/json/bundles/{self.branch_server.bundle_id.id}/batches', 200)
|
||||
batch_ids = [ b['id'] for b in batches_infos]
|
||||
self.assertEqual(len(batch_ids), 1)
|
||||
self.assertNotIn(private_batch.id, batch_ids)
|
||||
|
||||
# Let's verify that the batches infos contains the commits informations too
|
||||
for commit in batches_infos[0]['commits']:
|
||||
self.assertIn(commit['hash'], ['aaaaaaa', 'cccccc'])
|
||||
|
||||
# check that a public user cannot access private project batches
|
||||
private_batches_infos = self.check_json_route(f'/runbot/json/bundles/{self.private_branch_server.bundle_id.id}/batches', 200)
|
||||
self.assertEqual(private_batches_infos, [])
|
||||
|
||||
commits_infos = self.check_json_route(batches_infos[0]['commits_url'], 200)
|
||||
self.check_json_route(commits_infos[0]['url'], 200)
|
||||
|
||||
# check that a public user cannot access private project commits
|
||||
self.check_json_route(f'/runbot/json/batches/{private_batch.id}/commits', 403)
|
||||
self.check_json_route(f'/runbot/json/commits/{self.initial_private_server_commit.id}', 403)
|
||||
|
||||
commit_links_infos = self.check_json_route(commits_infos[0]['commit_links_url'], 200)
|
||||
self.check_json_route(commit_links_infos[0]['url'], 200)
|
||||
|
||||
# check that a public user cannot access private project commit links
|
||||
private_commit_link = self.env['runbot.commit.link'].search([('commit_id', '=', self.initial_private_server_commit.id)], limit=1)
|
||||
self.check_json_route(f'/runbot/json/commit_links/{private_commit_link.id}', 403)
|
||||
|
||||
server_slot_infos = list(filter(lambda slot: slot['trigger_name'] == 'Server trigger', self.check_json_route(batches_infos[0]['slots_url'], 200)))
|
||||
|
||||
# check that a public user cannot access private project batch slots
|
||||
self.check_json_route(f'/runbot/json/batches/{private_batch.id}/slots', 403)
|
||||
private_slot = self.env['runbot.batch.slot'].search([('batch_id', '=', private_batch.id)], limit=1)
|
||||
self.check_json_route(f'/runbot/json/batch_slots/{private_slot.id}', 403)
|
||||
|
||||
server_build_infos = self.check_json_route(server_slot_infos[0]['build_url'], 200)
|
||||
self.assertEqual(server_build_infos[0]['trigger'], 'Server trigger')
|
||||
|
||||
# check that a public user cannot access private project build
|
||||
self.check_json_route(f'/runbot/json/batches/{private_batch.id}/builds', 403)
|
||||
private_build = self.env['runbot.build'].search([('params_id.project_id','=', self.private_project.id)])
|
||||
self.check_json_route(f'/runbot/json/builds/{private_build.id}', 403)
|
Loading…
Reference in New Issue
Block a user