diff --git a/data/model/legacy.py b/data/model/legacy.py
index 2feba5a82..dd6a10121 100644
--- a/data/model/legacy.py
+++ b/data/model/legacy.py
@@ -2291,10 +2291,12 @@ def load_token_data(code):
def _get_build_base_query():
return (RepositoryBuild
.select(RepositoryBuild, RepositoryBuildTrigger, BuildTriggerService, Repository,
- Namespace)
+ Namespace, User)
.join(Repository)
.join(Namespace, on=(Repository.namespace_user == Namespace.id))
.switch(RepositoryBuild)
+ .join(User, JOIN_LEFT_OUTER)
+ .switch(RepositoryBuild)
.join(RepositoryBuildTrigger, JOIN_LEFT_OUTER)
.join(BuildTriggerService, JOIN_LEFT_OUTER)
.order_by(RepositoryBuild.started.desc()))
diff --git a/endpoints/api/build.py b/endpoints/api/build.py
index a784c4f84..385e9288c 100644
--- a/endpoints/api/build.py
+++ b/endpoints/api/build.py
@@ -45,7 +45,7 @@ def user_view(user):
'is_robot': user.robot,
}
-def trigger_view(trigger, can_read=False, can_admin=False):
+def trigger_view(trigger, can_read=False, can_admin=False, for_build=False):
if trigger and trigger.uuid:
build_trigger = BuildTriggerHandler.get_handler(trigger)
build_source = build_trigger.config.get('build_source')
@@ -55,17 +55,28 @@ def trigger_view(trigger, can_read=False, can_admin=False):
if can_admin:
can_read = True
- return {
- 'service': trigger.service.name,
- 'build_source': build_source if can_read else None,
- 'config': build_trigger.config if can_admin else {},
+ is_connected_user = False
+ if (can_admin and get_authenticated_user() and
+ trigger.connected_user_id == get_authenticated_user().id):
+ is_connected_user = True
+
+ trigger_data = {
'id': trigger.uuid,
- 'connected_user': trigger.connected_user.username,
+ 'service': trigger.service.name,
'is_active': build_trigger.is_active(),
- 'pull_robot': user_view(trigger.pull_robot) if trigger.pull_robot else None,
+
+ 'build_source': build_source if can_read else None,
'repository_url': repo_url if can_read else None,
+
+ 'config': build_trigger.config if can_admin else {},
+ 'is_connected_user': is_connected_user,
}
+ if not for_build and can_admin and trigger.pull_robot:
+ trigger_data['pull_robot'] = user_view(trigger.pull_robot)
+
+ return trigger_data
+
return None
@@ -111,7 +122,7 @@ def build_status_view(build_obj):
'tags': job_config.get('docker_tags', []),
'manual_user': job_config.get('manual_user', None),
'is_writer': can_write,
- 'trigger': trigger_view(build_obj.trigger, can_read, can_admin),
+ 'trigger': trigger_view(build_obj.trigger, can_read, can_admin, for_build=True),
'trigger_metadata': job_config.get('trigger_metadata', None) if can_read else None,
'resource_key': build_obj.resource_key,
'pull_robot': user_view(build_obj.pull_robot) if build_obj.pull_robot else None,
diff --git a/static/directives/repo-view/repo-panel-builds.html b/static/directives/repo-view/repo-panel-builds.html
index d4f2b1db7..6db82a7cb 100644
--- a/static/directives/repo-view/repo-panel-builds.html
+++ b/static/directives/repo-view/repo-panel-builds.html
@@ -146,7 +146,7 @@
View Credentials
+ ng-class="trigger.is_connected_user ? '' : 'disabled'">
Run Trigger Now
diff --git a/static/js/directives/repo-view/repo-panel-builds.js b/static/js/directives/repo-view/repo-panel-builds.js
index d52d1de00..a1d8fdd31 100644
--- a/static/js/directives/repo-view/repo-panel-builds.js
+++ b/static/js/directives/repo-view/repo-panel-builds.js
@@ -197,9 +197,9 @@ angular.module('quay').directive('repoPanelBuilds', function () {
};
$scope.askRunTrigger = function(trigger) {
- if ($scope.user.username != trigger.connected_user) {
- bootbox.alert('For security reasons, only user "' + trigger.connected_user +
- '" can manually invoke this trigger');
+ if (!trigger.is_connected_user) {
+ bootbox.alert('For security reasons, only the user that created this trigger can ' +
+ 'manually invoke this trigger');
return;
}
diff --git a/test/test_api_usage.py b/test/test_api_usage.py
index 012375aa2..4dc012ae6 100644
--- a/test/test_api_usage.py
+++ b/test/test_api_usage.py
@@ -6,6 +6,8 @@ import json as py_json
from urllib import urlencode
from urlparse import urlparse, urlunparse, parse_qs
+from playhouse.test_utils import assert_query_count
+
from endpoints.api import api_bp, api
from endpoints.building import PreparedBuild
from endpoints.webhooks import webhooks
@@ -1544,16 +1546,18 @@ class TestRepoBuilds(ApiTestCase):
def test_getrepo_nobuilds(self):
self.login(ADMIN_ACCESS_USER)
- json = self.getJsonResponse(RepositoryBuildList,
- params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
+ with assert_query_count(4):
+ json = self.getJsonResponse(RepositoryBuildList,
+ params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
assert len(json['builds']) == 0
def test_getrepobuilds(self):
self.login(ADMIN_ACCESS_USER)
- json = self.getJsonResponse(RepositoryBuildList,
- params=dict(repository=ADMIN_ACCESS_USER + '/building'))
+ with assert_query_count(4):
+ json = self.getJsonResponse(RepositoryBuildList,
+ params=dict(repository=ADMIN_ACCESS_USER + '/building'))
assert len(json['builds']) > 0
build = json['builds'][-1]