@@ -167,7 +167,8 @@ angular.module('registryUI.images', [
167167. directive ( 'registryImageBody' , [
168168 'imageLayers' ,
169169 'imageDockerConfig' ,
170- function ( imageLayers , imageDockerConfig ) {
170+ 'imageSignatures' ,
171+ function ( imageLayers , imageDockerConfig , imageSignatures ) {
171172 return {
172173 restrict : 'E' ,
173174 scope : {
@@ -180,6 +181,7 @@ angular.module('registryUI.images', [
180181 scope . layers = imageLayers ( image ) ;
181182 scope . config = imageDockerConfig ( image ) ;
182183 scope . labels = scope . config . Labels ;
184+ scope . signatures = imageSignatures ( image ) ;
183185 if ( angular . equals ( { } , scope . labels ) )
184186 scope . labels = null ;
185187 } ) ;
@@ -234,6 +236,37 @@ angular.module('registryUI.images', [
234236 }
235237] )
236238
239+ . directive ( 'registryImageSignatures' , [
240+ 'imageSignatures' ,
241+ function ( imageSignatures ) {
242+ return {
243+ restrict : 'E' ,
244+ scope : {
245+ image : '=' ,
246+ } ,
247+ templateUrl : 'registry-image-widgets/views/image-signatures.html' ,
248+ link : function ( scope , element , attrs ) {
249+ scope . signatureDetails = function signatureDetails ( signature ) {
250+ var result = "" ;
251+ if ( signature . conditions ) {
252+ var condition = signature . conditions . find ( function ( condition ) {
253+ return condition . type === "Trusted" ;
254+ } ) ;
255+ if ( condition !== undefined ) {
256+ result = condition . reason + " / " + condition . message ;
257+ }
258+ }
259+ return result ;
260+ } ;
261+
262+ scope . $watch ( "image" , function ( image ) {
263+ scope . signatures = imageSignatures ( image ) ;
264+ } ) ;
265+ }
266+ } ;
267+ }
268+ ] )
269+
237270. directive ( 'registryImageMeta' , [
238271 'imageDockerConfig' ,
239272 function ( imageDockerConfig ) {
@@ -312,18 +345,85 @@ angular.module('registryUI.images', [
312345 }
313346] )
314347
348+ . factory ( 'imageSignatures' , [
349+ 'WeakMap' ,
350+ function ( WeakMap ) {
351+ var weak = new WeakMap ( ) ;
352+
353+ return function ( image ) {
354+ if ( ! image )
355+ return [ ] ;
356+ var signatures = weak . get ( image ) ;
357+
358+
359+ var signatureStatus = function ( signature ) {
360+ var trusted = "Unverified" ;
361+ if ( signature . conditions ) {
362+ var condition = signature . conditions . find ( function ( condition ) {
363+ return condition . type === "Trusted" ;
364+ } ) ;
365+ if ( condition !== undefined ) {
366+ trusted = "Verified" ;
367+ } else {
368+ // Failed info not available
369+ // https://github.com/openshift/origin/issues/16301
370+ trusted = "Failed verification" ;
371+ }
372+ }
373+ return trusted ;
374+ } ;
375+
376+ if ( ! signatures && image . signatures ) {
377+ signatures = [ ] ;
378+ image . signatures . forEach ( function ( signature ) {
379+ signature . verified = signatureStatus ( signature ) ;
380+ signatures . push ( signature ) ;
381+ } ) ;
382+ weak . set ( image , signatures ) ;
383+ }
384+
385+ return signatures || [ ] ;
386+ } ;
387+ }
388+ ] )
389+
315390. factory ( 'registryImageListingFunc' , [
316391 'imagestreamTags' ,
317392 'imagestreamTagFromName' ,
393+ 'imageSignatures' ,
318394 '$location' ,
319- function ( imagestreamTags , imagestreamTagFromName , $location ) {
395+ function ( imagestreamTags , imagestreamTagFromName , imageSignatures , $location ) {
320396 return function ( scope , element , attrs ) {
321397 scope . imagestreamTags = imagestreamTags ;
322398 scope . imagestreamPath = scope . imagestreamFunc ( ) ;
323399 scope . imageByTag = scope . imageByTagFunc ( ) ;
324400 scope . imageTagNames = scope . imageTagNamesFunc ( ) ;
325401 scope . sharedImages = scope . sharedImagesFunc ( ) ;
326402 scope . imagestreamTagFromName = imagestreamTagFromName ;
403+ scope . imageSignatures = imageSignatures ;
404+
405+ scope . overallVerification = function overallVerification ( tag ) {
406+ var image , signature , signatures ;
407+ var overall = "Unverified" ;
408+
409+ image = scope . imageByTag ( tag . status ) ;
410+ signatures = scope . imageSignatures ( image ) ;
411+
412+ if ( signatures . length === 0 ) {
413+ return "Unsigned" ;
414+ } else {
415+ signatures . forEach ( function ( signature ) {
416+ var status = signature . verified ;
417+ if ( status === "Failed verification" || overall === "Failed verification" || overall === undefined ) {
418+ overall = status ;
419+ } else if ( status !== "Failed verification" ) {
420+ overall = status ;
421+ }
422+ } ) ;
423+ }
424+
425+ return overall ;
426+ } ;
327427
328428 /* Called when someone clicks on a row */
329429 scope . imagestreamActivate = function imagestreamActivate ( imagestream , tag , ev ) {
@@ -410,7 +510,8 @@ angular.module('registryUI.images', [
410510. directive ( 'registryImagePanel' , [
411511 'imageDockerConfig' ,
412512 'imageLayers' ,
413- function ( imageDockerConfig , imageLayers ) {
513+ 'imageSignatures' ,
514+ function ( imageDockerConfig , imageLayers , imageSignatures ) {
414515 return {
415516 restrict : 'E' ,
416517 transclude : true ,
@@ -435,6 +536,7 @@ angular.module('registryUI.images', [
435536 scope . layers = imageLayers ( scope . image ) ;
436537 scope . config = imageDockerConfig ( scope . image ) ;
437538 scope . labels = scope . config . Labels ;
539+ scope . signatures = imageSignatures ( scope . image ) ;
438540 if ( scope . imageTagNames )
439541 scope . names = scope . imageTagNames ( scope . image ) ;
440542 }
0 commit comments