github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-config/configtx/application_test.go (about)

     1  /*
     2  Copyright IBM Corp All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package configtx
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/base64"
    12  	"fmt"
    13  	"github.com/hellobchain/newcryptosm/ecdsa"
    14  	"github.com/hellobchain/newcryptosm/x509"
    15  	"github.com/hellobchain/third_party/hyperledger/fabric-config/configtx/internal/policydsl"
    16  	"github.com/hellobchain/third_party/hyperledger/fabric-config/protolator"
    17  	"github.com/hellobchain/third_party/hyperledger/fabric-config/protolator/protoext/peerext"
    18  	"math/big"
    19  	"testing"
    20  
    21  	"github.com/golang/protobuf/proto"
    22  	cb "github.com/hyperledger/fabric-protos-go/common"
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  func TestNewApplicationGroup(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	gt := NewGomegaWithT(t)
    30  
    31  	application, _ := baseApplication(t)
    32  
    33  	expectedApplicationGroup := `
    34  {
    35  	"groups": {
    36  		"Org1": {
    37  			"groups": {},
    38  			"mod_policy": "",
    39  			"policies": {},
    40  			"values": {},
    41  			"version": "0"
    42  		},
    43  		"Org2": {
    44  			"groups": {},
    45  			"mod_policy": "",
    46  			"policies": {},
    47  			"values": {},
    48  			"version": "0"
    49  		}
    50  	},
    51  	"mod_policy": "Admins",
    52  	"policies": {
    53  		"Admins": {
    54  			"mod_policy": "Admins",
    55  			"policy": {
    56  				"type": 3,
    57  				"value": {
    58  					"rule": "MAJORITY",
    59  					"sub_policy": "Admins"
    60  				}
    61  			},
    62  			"version": "0"
    63  		},
    64  		"Readers": {
    65  			"mod_policy": "Admins",
    66  			"policy": {
    67  				"type": 3,
    68  				"value": {
    69  					"rule": "ANY",
    70  					"sub_policy": "Readers"
    71  				}
    72  			},
    73  			"version": "0"
    74  		},
    75  		"Writers": {
    76  			"mod_policy": "Admins",
    77  			"policy": {
    78  				"type": 3,
    79  				"value": {
    80  					"rule": "ANY",
    81  					"sub_policy": "Writers"
    82  				}
    83  			},
    84  			"version": "0"
    85  		}
    86  	},
    87  	"values": {
    88  		"ACLs": {
    89  			"mod_policy": "Admins",
    90  			"value": "CgwKBGFjbDESBAoCaGk=",
    91  			"version": "0"
    92  		},
    93  		"Capabilities": {
    94  			"mod_policy": "Admins",
    95  			"value": "CggKBFYxXzMSAA==",
    96  			"version": "0"
    97  		}
    98  	},
    99  	"version": "0"
   100  }
   101  `
   102  
   103  	applicationGroup, err := newApplicationGroupTemplate(application)
   104  	gt.Expect(err).NotTo(HaveOccurred())
   105  
   106  	expectedApplication := &cb.ConfigGroup{}
   107  	err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedApplicationGroup), expectedApplication)
   108  	gt.Expect(err).ToNot(HaveOccurred())
   109  	gt.Expect(applicationGroup).To(Equal(expectedApplication))
   110  }
   111  
   112  func TestNewApplicationGroupFailure(t *testing.T) {
   113  	t.Parallel()
   114  
   115  	tests := []struct {
   116  		testName       string
   117  		applicationMod func(*Application)
   118  		expectedErr    string
   119  	}{
   120  		{
   121  			testName: "When application group policy is empty",
   122  			applicationMod: func(a *Application) {
   123  				a.Policies = nil
   124  			},
   125  			expectedErr: "no policies defined",
   126  		},
   127  		{
   128  			testName: "When no Admins policies are defined",
   129  			applicationMod: func(application *Application) {
   130  				delete(application.Policies, AdminsPolicyKey)
   131  			},
   132  			expectedErr: "no Admins policy defined",
   133  		},
   134  		{
   135  			testName: "When no Readers policies are defined",
   136  			applicationMod: func(application *Application) {
   137  				delete(application.Policies, ReadersPolicyKey)
   138  			},
   139  			expectedErr: "no Readers policy defined",
   140  		},
   141  		{
   142  			testName: "When no Writers policies are defined",
   143  			applicationMod: func(application *Application) {
   144  				delete(application.Policies, WritersPolicyKey)
   145  			},
   146  			expectedErr: "no Writers policy defined",
   147  		},
   148  		{
   149  			testName: "When ImplicitMetaPolicy rules' subpolicy is missing",
   150  			applicationMod: func(application *Application) {
   151  				application.Policies[ReadersPolicyKey] = Policy{
   152  					Rule: "ALL",
   153  					Type: ImplicitMetaPolicyType,
   154  				}
   155  			},
   156  			expectedErr: "invalid implicit meta policy rule: 'ALL': expected two space separated " +
   157  				"tokens, but got 1",
   158  		},
   159  		{
   160  			testName: "When ImplicitMetaPolicy rule is invalid",
   161  			applicationMod: func(application *Application) {
   162  				application.Policies[ReadersPolicyKey] = Policy{
   163  					Rule: "ANYY Readers",
   164  					Type: ImplicitMetaPolicyType,
   165  				}
   166  			},
   167  			expectedErr: "invalid implicit meta policy rule: 'ANYY Readers': unknown rule type " +
   168  				"'ANYY', expected ALL, ANY, or MAJORITY",
   169  		},
   170  		{
   171  			testName: "When SignatureTypePolicy rule is invalid",
   172  			applicationMod: func(application *Application) {
   173  				application.Policies[ReadersPolicyKey] = Policy{
   174  					Rule: "ANYY Readers",
   175  					Type: SignaturePolicyType,
   176  				}
   177  			},
   178  			expectedErr: "invalid signature policy rule: 'ANYY Readers': Cannot transition " +
   179  				"token types from VARIABLE [ANYY] to VARIABLE [Readers]",
   180  		},
   181  		{
   182  			testName: "When ImplicitMetaPolicy type is unknown policy type",
   183  			applicationMod: func(application *Application) {
   184  				application.Policies[ReadersPolicyKey] = Policy{
   185  					Type: "GreenPolicy",
   186  				}
   187  			},
   188  			expectedErr: "unknown policy type: GreenPolicy",
   189  		},
   190  	}
   191  
   192  	for _, tt := range tests {
   193  		tt := tt // capture range variable
   194  		t.Run(tt.testName, func(t *testing.T) {
   195  			t.Parallel()
   196  
   197  			gt := NewGomegaWithT(t)
   198  
   199  			application, _ := baseApplication(t)
   200  			tt.applicationMod(&application)
   201  
   202  			configGrp, err := newApplicationGroupTemplate(application)
   203  			gt.Expect(err).To(MatchError(tt.expectedErr))
   204  			gt.Expect(configGrp).To(BeNil())
   205  		})
   206  	}
   207  }
   208  
   209  func TestAppOrgAddAnchorPeer(t *testing.T) {
   210  	t.Parallel()
   211  
   212  	gt := NewGomegaWithT(t)
   213  
   214  	baseApplicationConf, _ := baseApplication(t)
   215  
   216  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
   217  	gt.Expect(err).NotTo(HaveOccurred())
   218  
   219  	config := &cb.Config{
   220  		ChannelGroup: &cb.ConfigGroup{
   221  			Groups: map[string]*cb.ConfigGroup{
   222  				ApplicationGroupKey: applicationGroup,
   223  			},
   224  			Values:   map[string]*cb.ConfigValue{},
   225  			Policies: map[string]*cb.ConfigPolicy{},
   226  		},
   227  	}
   228  
   229  	c := New(config)
   230  
   231  	newOrg1AnchorPeer := Address{
   232  		Host: "host3",
   233  		Port: 123,
   234  	}
   235  
   236  	newOrg2AnchorPeer := Address{
   237  		Host: "host4",
   238  		Port: 123,
   239  	}
   240  
   241  	expectedUpdatedConfigJSON := `
   242  {
   243  	"channel_group": {
   244  		"groups": {
   245  			"Application": {
   246  				"groups": {
   247  					"Org1": {
   248  						"groups": {},
   249  						"mod_policy": "",
   250  						"policies": {},
   251  						"values": {
   252  							"AnchorPeers": {
   253  								"mod_policy": "Admins",
   254  								"value": {
   255  									"anchor_peers": [
   256  									{
   257  									"host": "host3",
   258  									"port": 123
   259  									}
   260  									]
   261  								},
   262  								"version": "0"
   263  							}
   264  						},
   265  						"version": "0"
   266  					},
   267  					"Org2": {
   268  						"groups": {},
   269  						"mod_policy": "",
   270  						"policies": {},
   271  						"values": {
   272  							"AnchorPeers": {
   273  								"mod_policy": "Admins",
   274  								"value": {
   275  									"anchor_peers": [
   276  									{
   277  									"host": "host4",
   278  									"port": 123
   279  									}
   280  									]
   281  								},
   282  								"version": "0"
   283  							}
   284  						},
   285  						"version": "0"
   286  					}
   287  				},
   288  				"mod_policy": "Admins",
   289  				"policies": {
   290  					"Admins": {
   291  						"mod_policy": "Admins",
   292  						"policy": {
   293  							"type": 3,
   294  							"value": {
   295  								"rule": "MAJORITY",
   296  								"sub_policy": "Admins"
   297  							}
   298  						},
   299  						"version": "0"
   300  					},
   301  					"Readers": {
   302  						"mod_policy": "Admins",
   303  						"policy": {
   304  							"type": 3,
   305  							"value": {
   306  								"rule": "ANY",
   307  								"sub_policy": "Readers"
   308  							}
   309  						},
   310  						"version": "0"
   311  					},
   312  					"Writers": {
   313  						"mod_policy": "Admins",
   314  						"policy": {
   315  							"type": 3,
   316  							"value": {
   317  								"rule": "ANY",
   318  								"sub_policy": "Writers"
   319  							}
   320  						},
   321  						"version": "0"
   322  					}
   323  				},
   324  				"values": {
   325  					"ACLs": {
   326  						"mod_policy": "Admins",
   327  						"value": {
   328  							"acls": {
   329  								"acl1": {
   330  									"policy_ref": "hi"
   331  								}
   332  							}
   333  						},
   334  						"version": "0"
   335  					},
   336  					"Capabilities": {
   337  						"mod_policy": "Admins",
   338  						"value": {
   339  							"capabilities": {
   340  								"V1_3": {}
   341  							}
   342  						},
   343  						"version": "0"
   344  					}
   345  				},
   346  				"version": "0"
   347  			}
   348  		},
   349  		"mod_policy": "",
   350  		"policies": {},
   351  		"values": {},
   352  		"version": "0"
   353  	},
   354  	"sequence": "0"
   355  }
   356  `
   357  
   358  	expectedUpdatedConfig := &cb.Config{}
   359  
   360  	err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedUpdatedConfigJSON), expectedUpdatedConfig)
   361  	gt.Expect(err).ToNot(HaveOccurred())
   362  
   363  	err = c.Application().Organization("Org1").AddAnchorPeer(newOrg1AnchorPeer)
   364  	gt.Expect(err).NotTo(HaveOccurred())
   365  
   366  	err = c.Application().Organization("Org2").AddAnchorPeer(newOrg2AnchorPeer)
   367  	gt.Expect(err).NotTo(HaveOccurred())
   368  
   369  	gt.Expect(proto.Equal(c.updated, expectedUpdatedConfig)).To(BeTrue())
   370  }
   371  
   372  func TestAppOrgRemoveAnchorPeer(t *testing.T) {
   373  	t.Parallel()
   374  
   375  	gt := NewGomegaWithT(t)
   376  
   377  	baseApplicationConf, _ := baseApplication(t)
   378  
   379  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
   380  	gt.Expect(err).NotTo(HaveOccurred())
   381  
   382  	config := &cb.Config{
   383  		ChannelGroup: &cb.ConfigGroup{
   384  			Groups: map[string]*cb.ConfigGroup{
   385  				"Application": applicationGroup,
   386  			},
   387  			Values:   map[string]*cb.ConfigValue{},
   388  			Policies: map[string]*cb.ConfigPolicy{},
   389  		},
   390  	}
   391  
   392  	c := New(config)
   393  
   394  	expectedUpdatedConfigJSON := `
   395  {
   396  	"channel_group": {
   397  		"groups": {
   398  			"Application": {
   399  				"groups": {
   400  					"Org1": {
   401  						"groups": {},
   402  						"mod_policy": "",
   403  						"policies": {},
   404  						"values": {
   405  							"AnchorPeers": {
   406  								"mod_policy": "Admins",
   407  								"value": {},
   408  								"version": "0"
   409  							}
   410  						},
   411  						"version": "0"
   412  					},
   413  					"Org2": {
   414  						"groups": {},
   415  						"mod_policy": "",
   416  						"policies": {},
   417  						"values": {},
   418  						"version": "0"
   419  					}
   420  				},
   421  				"mod_policy": "Admins",
   422  				"policies": {
   423  					"Admins": {
   424  						"mod_policy": "Admins",
   425  						"policy": {
   426  							"type": 3,
   427  							"value": {
   428  								"rule": "MAJORITY",
   429  								"sub_policy": "Admins"
   430  							}
   431  						},
   432  						"version": "0"
   433  					},
   434  					"Readers": {
   435  						"mod_policy": "Admins",
   436  						"policy": {
   437  							"type": 3,
   438  							"value": {
   439  								"rule": "ANY",
   440  								"sub_policy": "Readers"
   441  							}
   442  						},
   443  						"version": "0"
   444  					},
   445  					"Writers": {
   446  						"mod_policy": "Admins",
   447  						"policy": {
   448  							"type": 3,
   449  							"value": {
   450  								"rule": "ANY",
   451  								"sub_policy": "Writers"
   452  							}
   453  						},
   454  						"version": "0"
   455  					}
   456  				},
   457  				"values": {
   458  					"ACLs": {
   459  						"mod_policy": "Admins",
   460  						"value": {
   461  							"acls": {
   462  								"acl1": {
   463  									"policy_ref": "hi"
   464  								}
   465  							}
   466  						},
   467  						"version": "0"
   468  					},
   469  					"Capabilities": {
   470  						"mod_policy": "Admins",
   471  						"value": {
   472  							"capabilities": {
   473  								"V1_3": {}
   474  							}
   475  						},
   476  						"version": "0"
   477  					}
   478  				},
   479  				"version": "0"
   480  			}
   481  		},
   482  		"mod_policy": "",
   483  		"policies": {},
   484  		"values": {},
   485  		"version": "0"
   486  	},
   487  	"sequence": "0"
   488  }
   489  `
   490  
   491  	anchorPeer1 := Address{Host: "host1", Port: 123}
   492  	applicationOrg1 := c.Application().Organization("Org1")
   493  	err = applicationOrg1.AddAnchorPeer(anchorPeer1)
   494  	gt.Expect(err).NotTo(HaveOccurred())
   495  	expectedUpdatedConfig := &cb.Config{}
   496  
   497  	err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedUpdatedConfigJSON), expectedUpdatedConfig)
   498  	gt.Expect(err).NotTo(HaveOccurred())
   499  
   500  	err = applicationOrg1.RemoveAnchorPeer(anchorPeer1)
   501  	gt.Expect(err).NotTo(HaveOccurred())
   502  
   503  	gt.Expect(proto.Equal(c.updated, expectedUpdatedConfig)).To(BeTrue())
   504  }
   505  
   506  func TestAppOrgRemoveAnchorPeerFailure(t *testing.T) {
   507  	t.Parallel()
   508  
   509  	tests := []struct {
   510  		testName           string
   511  		orgName            string
   512  		anchorPeerToRemove Address
   513  		configValues       map[string]*cb.ConfigValue
   514  		expectedErr        string
   515  	}{
   516  		{
   517  			testName:           "When the unmarshaling existing anchor peer proto fails",
   518  			orgName:            "Org1",
   519  			anchorPeerToRemove: Address{Host: "host1", Port: 123},
   520  			configValues:       map[string]*cb.ConfigValue{AnchorPeersKey: {Value: []byte("a little fire")}},
   521  			expectedErr:        "failed unmarshaling anchor peer endpoints for application org Org1: proto: can't skip unknown wire type 6",
   522  		},
   523  	}
   524  
   525  	for _, tt := range tests {
   526  		tt := tt
   527  		t.Run(tt.testName, func(t *testing.T) {
   528  			t.Parallel()
   529  
   530  			gt := NewGomegaWithT(t)
   531  
   532  			baseApplicationConf, _ := baseApplication(t)
   533  
   534  			applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
   535  			gt.Expect(err).NotTo(HaveOccurred())
   536  
   537  			applicationGroup.Groups["Org1"].Values = tt.configValues
   538  
   539  			config := &cb.Config{
   540  				ChannelGroup: &cb.ConfigGroup{
   541  					Groups: map[string]*cb.ConfigGroup{
   542  						"Application": applicationGroup,
   543  					},
   544  				},
   545  			}
   546  
   547  			c := New(config)
   548  
   549  			err = c.Application().Organization(tt.orgName).RemoveAnchorPeer(tt.anchorPeerToRemove)
   550  			gt.Expect(err).To(MatchError(tt.expectedErr))
   551  		})
   552  	}
   553  }
   554  
   555  func TestAnchorPeers(t *testing.T) {
   556  	t.Parallel()
   557  
   558  	gt := NewGomegaWithT(t)
   559  
   560  	channelGroup := newConfigGroup()
   561  
   562  	application, _ := baseApplication(t)
   563  	applicationGroup, err := newApplicationGroupTemplate(application)
   564  	gt.Expect(err).NotTo(HaveOccurred())
   565  
   566  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
   567  	config := &cb.Config{
   568  		ChannelGroup: channelGroup,
   569  	}
   570  
   571  	c := New(config)
   572  
   573  	anchorPeers, err := c.Application().Organization("Org1").AnchorPeers()
   574  	gt.Expect(err).NotTo(HaveOccurred())
   575  	gt.Expect(anchorPeers).To(BeNil())
   576  	gt.Expect(anchorPeers).To(HaveLen(0))
   577  
   578  	expectedAnchorPeer := Address{Host: "host1", Port: 123}
   579  	err = c.Application().Organization("Org1").AddAnchorPeer(expectedAnchorPeer)
   580  	gt.Expect(err).NotTo(HaveOccurred())
   581  
   582  	anchorPeers, err = c.Application().Organization("Org1").AnchorPeers()
   583  	gt.Expect(err).NotTo(HaveOccurred())
   584  	gt.Expect(anchorPeers).To(HaveLen(1))
   585  	gt.Expect(anchorPeers[0]).To(Equal(expectedAnchorPeer))
   586  
   587  	err = c.Application().Organization("Org1").RemoveAnchorPeer(expectedAnchorPeer)
   588  	gt.Expect(err).NotTo(HaveOccurred())
   589  
   590  	anchorPeers, err = c.Application().Organization("Org1").AnchorPeers()
   591  	gt.Expect(err).NotTo(HaveOccurred())
   592  	gt.Expect(anchorPeers).To(BeNil())
   593  	gt.Expect(anchorPeers).To(HaveLen(0))
   594  }
   595  
   596  func TestSetACL(t *testing.T) {
   597  	t.Parallel()
   598  
   599  	tests := []struct {
   600  		testName    string
   601  		configMod   func(*cb.Config)
   602  		newACL      map[string]string
   603  		expectedACL map[string]string
   604  		expectedErr string
   605  	}{
   606  		{
   607  			testName: "success",
   608  			newACL:   map[string]string{"acl2": "newACL"},
   609  			expectedACL: map[string]string{
   610  				"acl2": "newACL",
   611  			},
   612  			expectedErr: "",
   613  		},
   614  		{
   615  			testName: "ACL overwrite",
   616  			newACL:   map[string]string{"acl1": "overwrite acl"},
   617  			expectedACL: map[string]string{
   618  				"acl1": "overwrite acl",
   619  			},
   620  			expectedErr: "",
   621  		},
   622  	}
   623  
   624  	for _, tt := range tests {
   625  		tt := tt
   626  		t.Run(tt.testName, func(t *testing.T) {
   627  			t.Parallel()
   628  			gt := NewGomegaWithT(t)
   629  
   630  			channelGroup := newConfigGroup()
   631  			baseApplication, _ := baseApplication(t)
   632  			applicationGroup, err := newApplicationGroupTemplate(baseApplication)
   633  
   634  			channelGroup.Groups[ApplicationGroupKey] = applicationGroup
   635  			config := &cb.Config{
   636  				ChannelGroup: channelGroup,
   637  			}
   638  			if tt.configMod != nil {
   639  				tt.configMod(config)
   640  			}
   641  			c := New(config)
   642  
   643  			err = c.Application().SetACLs(tt.newACL)
   644  			if tt.expectedErr != "" {
   645  				gt.Expect(err).To(MatchError(tt.expectedErr))
   646  			} else {
   647  				gt.Expect(err).NotTo(HaveOccurred())
   648  				acls, err := c.Application().ACLs()
   649  				gt.Expect(err).NotTo(HaveOccurred())
   650  				gt.Expect(acls).To(Equal(tt.expectedACL))
   651  			}
   652  		})
   653  	}
   654  }
   655  
   656  func TestAppOrgRemoveACL(t *testing.T) {
   657  	t.Parallel()
   658  
   659  	tests := []struct {
   660  		testName    string
   661  		configMod   func(*cb.Config)
   662  		removeACL   []string
   663  		expectedACL map[string]string
   664  		expectedErr string
   665  	}{
   666  		{
   667  			testName:  "success",
   668  			removeACL: []string{"acl1", "acl2"},
   669  			expectedACL: map[string]string{
   670  				"acl3": "acl3Value",
   671  			},
   672  			expectedErr: "",
   673  		},
   674  		{
   675  			testName:  "remove non-existing acls",
   676  			removeACL: []string{"bad-acl1", "bad-acl2"},
   677  			expectedACL: map[string]string{
   678  				"acl1": "hi",
   679  				"acl2": "acl2Value",
   680  				"acl3": "acl3Value",
   681  			},
   682  			expectedErr: "",
   683  		},
   684  	}
   685  
   686  	for _, tt := range tests {
   687  		tt := tt
   688  		t.Run(tt.testName, func(t *testing.T) {
   689  			t.Parallel()
   690  			gt := NewGomegaWithT(t)
   691  
   692  			channelGroup := newConfigGroup()
   693  			baseApplication, _ := baseApplication(t)
   694  			baseApplication.ACLs["acl2"] = "acl2Value"
   695  			baseApplication.ACLs["acl3"] = "acl3Value"
   696  			applicationGroup, err := newApplicationGroupTemplate(baseApplication)
   697  
   698  			channelGroup.Groups[ApplicationGroupKey] = applicationGroup
   699  			config := &cb.Config{
   700  				ChannelGroup: channelGroup,
   701  			}
   702  			if tt.configMod != nil {
   703  				tt.configMod(config)
   704  			}
   705  
   706  			c := New(config)
   707  
   708  			err = c.Application().RemoveACLs(tt.removeACL)
   709  			if tt.expectedErr != "" {
   710  				gt.Expect(err).To(MatchError(tt.expectedErr))
   711  			} else {
   712  				gt.Expect(err).NotTo(HaveOccurred())
   713  				acls, err := c.Application().ACLs()
   714  				gt.Expect(err).NotTo(HaveOccurred())
   715  				gt.Expect(acls).To(Equal(tt.expectedACL))
   716  			}
   717  		})
   718  	}
   719  }
   720  
   721  func TestSetApplicationOrg(t *testing.T) {
   722  	t.Parallel()
   723  
   724  	gt := NewGomegaWithT(t)
   725  
   726  	application, _ := baseApplication(t)
   727  	appGroup, err := newApplicationGroup(application)
   728  	gt.Expect(err).NotTo(HaveOccurred())
   729  
   730  	config := &cb.Config{
   731  		ChannelGroup: &cb.ConfigGroup{
   732  			Groups: map[string]*cb.ConfigGroup{
   733  				"Application": appGroup,
   734  			},
   735  		},
   736  	}
   737  
   738  	c := New(config)
   739  
   740  	baseMSP, _ := baseMSP(t)
   741  	org := Organization{
   742  		Name:     "Org3",
   743  		Policies: applicationOrgStandardPolicies(),
   744  		MSP:      baseMSP,
   745  		AnchorPeers: []Address{
   746  			{
   747  				Host: "127.0.0.1",
   748  				Port: 7051,
   749  			},
   750  		},
   751  	}
   752  
   753  	certBase64, crlBase64 := certCRLBase64(t, org.MSP)
   754  	expectedConfigJSON := fmt.Sprintf(`
   755  {
   756  	"groups": {},
   757  	"mod_policy": "Admins",
   758  	"policies": {
   759  		"Admins": {
   760  			"mod_policy": "Admins",
   761  			"policy": {
   762  				"type": 3,
   763  				"value": {
   764  					"rule": "MAJORITY",
   765  					"sub_policy": "Admins"
   766  				}
   767  			},
   768  			"version": "0"
   769  		},
   770  		"Endorsement": {
   771  			"mod_policy": "Admins",
   772  			"policy": {
   773  				"type": 3,
   774  				"value": {
   775  					"rule": "MAJORITY",
   776  					"sub_policy": "Endorsement"
   777  				}
   778  			},
   779  			"version": "0"
   780  		},
   781  		"LifecycleEndorsement": {
   782  			"mod_policy": "Admins",
   783  			"policy": {
   784  				"type": 3,
   785  				"value": {
   786  					"rule": "MAJORITY",
   787  					"sub_policy": "Endorsement"
   788  				}
   789  			},
   790  			"version": "0"
   791  		},
   792  		"Readers": {
   793  			"mod_policy": "Admins",
   794  			"policy": {
   795  				"type": 3,
   796  				"value": {
   797  					"rule": "ANY",
   798  					"sub_policy": "Readers"
   799  				}
   800  			},
   801  			"version": "0"
   802  		},
   803  		"Writers": {
   804  			"mod_policy": "Admins",
   805  			"policy": {
   806  				"type": 3,
   807  				"value": {
   808  					"rule": "ANY",
   809  					"sub_policy": "Writers"
   810  				}
   811  			},
   812  			"version": "0"
   813  		}
   814  	},
   815  	"values": {
   816  		"AnchorPeers": {
   817  			"mod_policy": "Admins",
   818  			"value": {
   819  				"anchor_peers": [
   820  					{
   821  						"host": "127.0.0.1",
   822  						"port": 7051
   823  					}
   824  				]
   825  			},
   826  			"version": "0"
   827  		},
   828  		"MSP": {
   829  			"mod_policy": "Admins",
   830  			"value": {
   831  				"config": {
   832  					"admins": [
   833  						"%[1]s"
   834  					],
   835  					"crypto_config": {
   836  						"identity_identifier_hash_function": "SHA256",
   837  						"signature_hash_family": "SHA3"
   838  					},
   839  					"fabric_node_ous": {
   840  						"admin_ou_identifier": {
   841  							"certificate": "%[1]s",
   842  							"organizational_unit_identifier": "OUID"
   843  						},
   844  						"client_ou_identifier": {
   845  							"certificate": "%[1]s",
   846  							"organizational_unit_identifier": "OUID"
   847  						},
   848  						"enable": false,
   849  						"orderer_ou_identifier": {
   850  							"certificate": "%[1]s",
   851  							"organizational_unit_identifier": "OUID"
   852  						},
   853  						"peer_ou_identifier": {
   854  							"certificate": "%[1]s",
   855  							"organizational_unit_identifier": "OUID"
   856  						}
   857  					},
   858  					"intermediate_certs": [
   859  						"%[1]s"
   860  					],
   861  					"name": "MSPID",
   862  					"organizational_unit_identifiers": [
   863  						{
   864  							"certificate": "%[1]s",
   865  							"organizational_unit_identifier": "OUID"
   866  						}
   867  					],
   868  					"revocation_list": [
   869  						"%[2]s"
   870  					],
   871  					"root_certs": [
   872  						"%[1]s"
   873  					],
   874  					"signing_identity": null,
   875  					"tls_intermediate_certs": [
   876  						"%[1]s"
   877  					],
   878  					"tls_root_certs": [
   879  						"%[1]s"
   880  					]
   881  				},
   882  				"type": 0
   883  			},
   884  			"version": "0"
   885  		}
   886  	},
   887  	"version": "0"
   888  }
   889  `, certBase64, crlBase64)
   890  
   891  	err = c.Application().SetOrganization(org)
   892  	gt.Expect(err).NotTo(HaveOccurred())
   893  
   894  	actualApplicationConfigGroup := c.Application().Organization("Org3").orgGroup
   895  	buf := bytes.Buffer{}
   896  	err = protolator.DeepMarshalJSON(&buf, &peerext.DynamicApplicationOrgGroup{ConfigGroup: actualApplicationConfigGroup})
   897  	gt.Expect(err).NotTo(HaveOccurred())
   898  	gt.Expect(buf.String()).To(MatchJSON(expectedConfigJSON))
   899  }
   900  
   901  func TestSetApplicationOrgFailures(t *testing.T) {
   902  	t.Parallel()
   903  
   904  	gt := NewGomegaWithT(t)
   905  
   906  	application, _ := baseApplication(t)
   907  	appGroup, err := newApplicationGroupTemplate(application)
   908  	gt.Expect(err).NotTo(HaveOccurred())
   909  
   910  	config := &cb.Config{
   911  		ChannelGroup: &cb.ConfigGroup{
   912  			Groups: map[string]*cb.ConfigGroup{
   913  				"Application": appGroup,
   914  			},
   915  		},
   916  	}
   917  
   918  	c := New(config)
   919  
   920  	org := Organization{
   921  		Name: "Org3",
   922  	}
   923  
   924  	err = c.Application().SetOrganization(org)
   925  	gt.Expect(err).To(MatchError("failed to create application org Org3: no policies defined"))
   926  }
   927  
   928  func TestApplicationConfiguration(t *testing.T) {
   929  	t.Parallel()
   930  	gt := NewGomegaWithT(t)
   931  
   932  	baseApplicationConf, _ := baseApplication(t)
   933  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
   934  	gt.Expect(err).NotTo(HaveOccurred())
   935  
   936  	config := &cb.Config{
   937  		ChannelGroup: &cb.ConfigGroup{
   938  			Groups: map[string]*cb.ConfigGroup{
   939  				ApplicationGroupKey: applicationGroup,
   940  			},
   941  		},
   942  	}
   943  
   944  	c := New(config)
   945  
   946  	for _, org := range baseApplicationConf.Organizations {
   947  		err = c.Application().SetOrganization(org)
   948  		gt.Expect(err).NotTo(HaveOccurred())
   949  	}
   950  
   951  	applicationConfig, err := c.Application().Configuration()
   952  	gt.Expect(err).NotTo(HaveOccurred())
   953  	gt.Expect(applicationConfig.ACLs).To(Equal(baseApplicationConf.ACLs))
   954  	gt.Expect(applicationConfig.Capabilities).To(Equal(baseApplicationConf.Capabilities))
   955  	gt.Expect(applicationConfig.Policies).To(Equal(baseApplicationConf.Policies))
   956  	gt.Expect(applicationConfig.Organizations).To(ContainElements(baseApplicationConf.Organizations))
   957  }
   958  
   959  func TestApplicationConfigurationFailure(t *testing.T) {
   960  	t.Parallel()
   961  
   962  	tests := []struct {
   963  		testName    string
   964  		configMod   func(ConfigTx, Application, *GomegaWithT)
   965  		expectedErr string
   966  	}{
   967  		{
   968  			testName: "Retrieving application org failed",
   969  			configMod: func(c ConfigTx, appOrg Application, gt *GomegaWithT) {
   970  				for _, org := range appOrg.Organizations {
   971  					if org.Name == "Org2" {
   972  						err := c.Application().SetOrganization(org)
   973  						gt.Expect(err).NotTo(HaveOccurred())
   974  					}
   975  				}
   976  			},
   977  			expectedErr: "retrieving application org Org1: config does not contain value for MSP",
   978  		},
   979  	}
   980  
   981  	for _, tt := range tests {
   982  		tt := tt
   983  		t.Run(tt.testName, func(t *testing.T) {
   984  			t.Parallel()
   985  
   986  			gt := NewGomegaWithT(t)
   987  
   988  			baseApplicationConf, _ := baseApplication(t)
   989  			applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
   990  			gt.Expect(err).NotTo(HaveOccurred())
   991  
   992  			config := &cb.Config{
   993  				ChannelGroup: &cb.ConfigGroup{
   994  					Groups: map[string]*cb.ConfigGroup{
   995  						ApplicationGroupKey: applicationGroup,
   996  					},
   997  				},
   998  			}
   999  
  1000  			c := New(config)
  1001  			if tt.configMod != nil {
  1002  				tt.configMod(c, baseApplicationConf, gt)
  1003  			}
  1004  
  1005  			c = New(c.updated)
  1006  
  1007  			_, err = c.Application().Configuration()
  1008  			gt.Expect(err).To(MatchError(tt.expectedErr))
  1009  		})
  1010  	}
  1011  }
  1012  
  1013  func TestApplicationACLs(t *testing.T) {
  1014  	t.Parallel()
  1015  
  1016  	gt := NewGomegaWithT(t)
  1017  
  1018  	baseApplicationConf, _ := baseApplication(t)
  1019  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
  1020  	gt.Expect(err).NotTo(HaveOccurred())
  1021  
  1022  	config := &cb.Config{
  1023  		ChannelGroup: &cb.ConfigGroup{
  1024  			Groups: map[string]*cb.ConfigGroup{
  1025  				ApplicationGroupKey: applicationGroup,
  1026  			},
  1027  		},
  1028  	}
  1029  
  1030  	c := New(config)
  1031  
  1032  	applicationACLs, err := c.Application().ACLs()
  1033  	gt.Expect(err).NotTo(HaveOccurred())
  1034  	gt.Expect(applicationACLs).To(Equal(baseApplicationConf.ACLs))
  1035  }
  1036  
  1037  func TestEmptyApplicationACLs(t *testing.T) {
  1038  	t.Parallel()
  1039  
  1040  	gt := NewGomegaWithT(t)
  1041  
  1042  	baseApplicationConf, _ := baseApplication(t)
  1043  	baseApplicationConf.ACLs = nil
  1044  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
  1045  	gt.Expect(err).NotTo(HaveOccurred())
  1046  
  1047  	config := &cb.Config{
  1048  		ChannelGroup: &cb.ConfigGroup{
  1049  			Groups: map[string]*cb.ConfigGroup{
  1050  				ApplicationGroupKey: applicationGroup,
  1051  			},
  1052  		},
  1053  	}
  1054  
  1055  	c := New(config)
  1056  
  1057  	applicationACLs, err := c.Application().ACLs()
  1058  	gt.Expect(err).NotTo(HaveOccurred())
  1059  	gt.Expect(applicationACLs).To(BeNil())
  1060  }
  1061  
  1062  func TestApplicationACLsFailure(t *testing.T) {
  1063  	t.Parallel()
  1064  
  1065  	gt := NewGomegaWithT(t)
  1066  
  1067  	baseApplicationConf, _ := baseApplication(t)
  1068  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
  1069  	gt.Expect(err).NotTo(HaveOccurred())
  1070  
  1071  	config := &cb.Config{
  1072  		ChannelGroup: &cb.ConfigGroup{
  1073  			Groups: map[string]*cb.ConfigGroup{
  1074  				ApplicationGroupKey: applicationGroup,
  1075  			},
  1076  		},
  1077  	}
  1078  
  1079  	config.ChannelGroup.Groups[ApplicationGroupKey].Values[ACLsKey] = &cb.ConfigValue{
  1080  		Value: []byte("another little fire"),
  1081  	}
  1082  
  1083  	c := New(config)
  1084  
  1085  	applicationACLs, err := c.Application().ACLs()
  1086  	gt.Expect(err).To(MatchError("unmarshaling ACLs: unexpected EOF"))
  1087  	gt.Expect(applicationACLs).To(BeNil())
  1088  }
  1089  
  1090  func TestApplicationCapabilities(t *testing.T) {
  1091  	t.Parallel()
  1092  
  1093  	gt := NewGomegaWithT(t)
  1094  
  1095  	baseApplicationConf, _ := baseApplication(t)
  1096  	applicationGroup, err := newApplicationGroupTemplate(baseApplicationConf)
  1097  	gt.Expect(err).NotTo(HaveOccurred())
  1098  
  1099  	config := &cb.Config{
  1100  		ChannelGroup: &cb.ConfigGroup{
  1101  			Groups: map[string]*cb.ConfigGroup{
  1102  				ApplicationGroupKey: applicationGroup,
  1103  			},
  1104  		},
  1105  	}
  1106  
  1107  	c := New(config)
  1108  
  1109  	applicationCapabilities, err := c.Application().Capabilities()
  1110  	gt.Expect(err).NotTo(HaveOccurred())
  1111  	gt.Expect(applicationCapabilities).To(Equal(baseApplicationConf.Capabilities))
  1112  
  1113  	// Delete the capabilities key and assert retrieval to return nil
  1114  	delete(c.Application().applicationGroup.Values, CapabilitiesKey)
  1115  	applicationCapabilities, err = c.Application().Capabilities()
  1116  	gt.Expect(err).NotTo(HaveOccurred())
  1117  	gt.Expect(applicationCapabilities).To(BeNil())
  1118  }
  1119  
  1120  func TestAppOrgAddApplicationCapability(t *testing.T) {
  1121  	t.Parallel()
  1122  
  1123  	tests := []struct {
  1124  		testName                string
  1125  		capability              string
  1126  		equalToOriginal         bool
  1127  		expectedConfigGroupJSON string
  1128  	}{
  1129  		{
  1130  			testName:        "success -- adding new capability",
  1131  			capability:      "new_capability",
  1132  			equalToOriginal: false,
  1133  			expectedConfigGroupJSON: `{
  1134  	"groups": {
  1135  		"Org1": {
  1136  			"groups": {},
  1137  			"mod_policy": "",
  1138  			"policies": {},
  1139  			"values": {},
  1140  			"version": "0"
  1141  		},
  1142  		"Org2": {
  1143  			"groups": {},
  1144  			"mod_policy": "",
  1145  			"policies": {},
  1146  			"values": {},
  1147  			"version": "0"
  1148  		}
  1149  	},
  1150  	"mod_policy": "Admins",
  1151  	"policies": {
  1152  		"Admins": {
  1153  			"mod_policy": "Admins",
  1154  			"policy": {
  1155  				"type": 3,
  1156  				"value": {
  1157  					"rule": "MAJORITY",
  1158  					"sub_policy": "Admins"
  1159  				}
  1160  			},
  1161  			"version": "0"
  1162  		},
  1163  		"Readers": {
  1164  			"mod_policy": "Admins",
  1165  			"policy": {
  1166  				"type": 3,
  1167  				"value": {
  1168  					"rule": "ANY",
  1169  					"sub_policy": "Readers"
  1170  				}
  1171  			},
  1172  			"version": "0"
  1173  		},
  1174  		"Writers": {
  1175  			"mod_policy": "Admins",
  1176  			"policy": {
  1177  				"type": 3,
  1178  				"value": {
  1179  					"rule": "ANY",
  1180  					"sub_policy": "Writers"
  1181  				}
  1182  			},
  1183  			"version": "0"
  1184  		}
  1185  	},
  1186  	"values": {
  1187  		"ACLs": {
  1188  			"mod_policy": "Admins",
  1189  			"value": {
  1190  				"acls": {
  1191  					"acl1": {
  1192  						"policy_ref": "hi"
  1193  					}
  1194  				}
  1195  			},
  1196  			"version": "0"
  1197  		},
  1198  		"Capabilities": {
  1199  			"mod_policy": "Admins",
  1200  			"value": {
  1201  				"capabilities": {
  1202  					"V1_3": {},
  1203  					"new_capability": {}
  1204  				}
  1205  			},
  1206  			"version": "0"
  1207  		}
  1208  	},
  1209  	"version": "0"
  1210  }
  1211  `,
  1212  		},
  1213  		{
  1214  			testName:        "success -- when capability already exists",
  1215  			capability:      "V1_3",
  1216  			equalToOriginal: true,
  1217  			expectedConfigGroupJSON: `{
  1218  	"groups": {
  1219  		"Org1": {
  1220  			"groups": {},
  1221  			"mod_policy": "",
  1222  			"policies": {},
  1223  			"values": {},
  1224  			"version": "0"
  1225  		},
  1226  		"Org2": {
  1227  			"groups": {},
  1228  			"mod_policy": "",
  1229  			"policies": {},
  1230  			"values": {},
  1231  			"version": "0"
  1232  		}
  1233  	},
  1234  	"mod_policy": "Admins",
  1235  	"policies": {
  1236  		"Admins": {
  1237  			"mod_policy": "Admins",
  1238  			"policy": {
  1239  				"type": 3,
  1240  				"value": {
  1241  					"rule": "MAJORITY",
  1242  					"sub_policy": "Admins"
  1243  				}
  1244  			},
  1245  			"version": "0"
  1246  		},
  1247  		"Readers": {
  1248  			"mod_policy": "Admins",
  1249  			"policy": {
  1250  				"type": 3,
  1251  				"value": {
  1252  					"rule": "ANY",
  1253  					"sub_policy": "Readers"
  1254  				}
  1255  			},
  1256  			"version": "0"
  1257  		},
  1258  		"Writers": {
  1259  			"mod_policy": "Admins",
  1260  			"policy": {
  1261  				"type": 3,
  1262  				"value": {
  1263  					"rule": "ANY",
  1264  					"sub_policy": "Writers"
  1265  				}
  1266  			},
  1267  			"version": "0"
  1268  		}
  1269  	},
  1270  	"values": {
  1271  		"ACLs": {
  1272  			"mod_policy": "Admins",
  1273  			"value": {
  1274  				"acls": {
  1275  					"acl1": {
  1276  						"policy_ref": "hi"
  1277  					}
  1278  				}
  1279  			},
  1280  			"version": "0"
  1281  		},
  1282  		"Capabilities": {
  1283  			"mod_policy": "Admins",
  1284  			"value": {
  1285  				"capabilities": {
  1286  					"V1_3": {}
  1287  				}
  1288  			},
  1289  			"version": "0"
  1290  		}
  1291  	},
  1292  	"version": "0"
  1293  }
  1294  `,
  1295  		},
  1296  	}
  1297  
  1298  	for _, tt := range tests {
  1299  		tt := tt
  1300  		t.Run(tt.testName, func(t *testing.T) {
  1301  			t.Parallel()
  1302  			gt := NewGomegaWithT(t)
  1303  
  1304  			baseApp, _ := baseApplication(t)
  1305  			appGroup, err := newApplicationGroupTemplate(baseApp)
  1306  			gt.Expect(err).NotTo(HaveOccurred())
  1307  
  1308  			config := &cb.Config{
  1309  				ChannelGroup: &cb.ConfigGroup{
  1310  					Groups: map[string]*cb.ConfigGroup{
  1311  						ApplicationGroupKey: appGroup,
  1312  					},
  1313  				},
  1314  			}
  1315  
  1316  			c := New(config)
  1317  
  1318  			err = c.Application().AddCapability(tt.capability)
  1319  			gt.Expect(err).NotTo(HaveOccurred())
  1320  
  1321  			updatedApplicationGroupJSON := bytes.Buffer{}
  1322  			err = protolator.DeepMarshalJSON(&updatedApplicationGroupJSON, &peerext.DynamicApplicationGroup{ConfigGroup: c.Application().applicationGroup})
  1323  			gt.Expect(err).NotTo(HaveOccurred())
  1324  			originalApplicationGroupJSON := bytes.Buffer{}
  1325  			err = protolator.DeepMarshalJSON(&originalApplicationGroupJSON, &peerext.DynamicApplicationGroup{ConfigGroup: c.original.ChannelGroup.Groups[ApplicationGroupKey]})
  1326  			gt.Expect(err).NotTo(HaveOccurred())
  1327  
  1328  			gt.Expect(updatedApplicationGroupJSON.String()).To(Equal(tt.expectedConfigGroupJSON))
  1329  			if !tt.equalToOriginal {
  1330  				gt.Expect(updatedApplicationGroupJSON).NotTo(Equal(originalApplicationGroupJSON))
  1331  			} else {
  1332  				gt.Expect(updatedApplicationGroupJSON).To(Equal(originalApplicationGroupJSON))
  1333  			}
  1334  		})
  1335  	}
  1336  }
  1337  
  1338  func TestAppOrgAddApplicationCapabilityFailures(t *testing.T) {
  1339  	t.Parallel()
  1340  
  1341  	tests := []struct {
  1342  		testName         string
  1343  		capability       string
  1344  		applicationGroup func(ag *cb.ConfigGroup)
  1345  		expectedErr      string
  1346  	}{
  1347  		{
  1348  			testName:   "when retrieving existing capabilities",
  1349  			capability: "V1_3",
  1350  			applicationGroup: func(ag *cb.ConfigGroup) {
  1351  				ag.Values = map[string]*cb.ConfigValue{
  1352  					CapabilitiesKey: {
  1353  						Value: []byte("foobar"),
  1354  					},
  1355  				}
  1356  			},
  1357  			expectedErr: "retrieving application capabilities: unmarshaling capabilities: proto: can't skip unknown wire type 6",
  1358  		},
  1359  	}
  1360  
  1361  	for _, tt := range tests {
  1362  		tt := tt
  1363  		t.Run(tt.testName, func(t *testing.T) {
  1364  			t.Parallel()
  1365  
  1366  			gt := NewGomegaWithT(t)
  1367  
  1368  			baseApp, _ := baseApplication(t)
  1369  			appGroup, err := newApplicationGroupTemplate(baseApp)
  1370  			gt.Expect(err).NotTo(HaveOccurred())
  1371  			tt.applicationGroup(appGroup)
  1372  
  1373  			config := &cb.Config{
  1374  				ChannelGroup: &cb.ConfigGroup{
  1375  					Groups: map[string]*cb.ConfigGroup{
  1376  						ApplicationGroupKey: appGroup,
  1377  					},
  1378  				},
  1379  			}
  1380  
  1381  			c := New(config)
  1382  
  1383  			err = c.Application().AddCapability(tt.capability)
  1384  			gt.Expect(err).To(MatchError(tt.expectedErr))
  1385  		})
  1386  	}
  1387  }
  1388  
  1389  func TestAppOrgRemoveApplicationCapability(t *testing.T) {
  1390  	t.Parallel()
  1391  
  1392  	gt := NewGomegaWithT(t)
  1393  
  1394  	baseApp, _ := baseApplication(t)
  1395  	appGroup, err := newApplicationGroupTemplate(baseApp)
  1396  	gt.Expect(err).NotTo(HaveOccurred())
  1397  
  1398  	config := &cb.Config{
  1399  		ChannelGroup: &cb.ConfigGroup{
  1400  			Groups: map[string]*cb.ConfigGroup{
  1401  				ApplicationGroupKey: appGroup,
  1402  			},
  1403  		},
  1404  	}
  1405  
  1406  	c := New(config)
  1407  
  1408  	expectedConfigGroupJSON := `{
  1409  	"groups": {
  1410  		"Org1": {
  1411  			"groups": {},
  1412  			"mod_policy": "",
  1413  			"policies": {},
  1414  			"values": {},
  1415  			"version": "0"
  1416  		},
  1417  		"Org2": {
  1418  			"groups": {},
  1419  			"mod_policy": "",
  1420  			"policies": {},
  1421  			"values": {},
  1422  			"version": "0"
  1423  		}
  1424  	},
  1425  	"mod_policy": "Admins",
  1426  	"policies": {
  1427  		"Admins": {
  1428  			"mod_policy": "Admins",
  1429  			"policy": {
  1430  				"type": 3,
  1431  				"value": {
  1432  					"rule": "MAJORITY",
  1433  					"sub_policy": "Admins"
  1434  				}
  1435  			},
  1436  			"version": "0"
  1437  		},
  1438  		"Readers": {
  1439  			"mod_policy": "Admins",
  1440  			"policy": {
  1441  				"type": 3,
  1442  				"value": {
  1443  					"rule": "ANY",
  1444  					"sub_policy": "Readers"
  1445  				}
  1446  			},
  1447  			"version": "0"
  1448  		},
  1449  		"Writers": {
  1450  			"mod_policy": "Admins",
  1451  			"policy": {
  1452  				"type": 3,
  1453  				"value": {
  1454  					"rule": "ANY",
  1455  					"sub_policy": "Writers"
  1456  				}
  1457  			},
  1458  			"version": "0"
  1459  		}
  1460  	},
  1461  	"values": {
  1462  		"ACLs": {
  1463  			"mod_policy": "Admins",
  1464  			"value": {
  1465  				"acls": {
  1466  					"acl1": {
  1467  						"policy_ref": "hi"
  1468  					}
  1469  				}
  1470  			},
  1471  			"version": "0"
  1472  		},
  1473  		"Capabilities": {
  1474  			"mod_policy": "Admins",
  1475  			"value": {
  1476  				"capabilities": {}
  1477  			},
  1478  			"version": "0"
  1479  		}
  1480  	},
  1481  	"version": "0"
  1482  }
  1483  `
  1484  	capability := "V1_3"
  1485  	err = c.Application().RemoveCapability(capability)
  1486  	gt.Expect(err).NotTo(HaveOccurred())
  1487  
  1488  	buf := bytes.Buffer{}
  1489  	err = protolator.DeepMarshalJSON(&buf, &peerext.DynamicApplicationGroup{ConfigGroup: c.updated.ChannelGroup.Groups[ApplicationGroupKey]})
  1490  	gt.Expect(err).NotTo(HaveOccurred())
  1491  
  1492  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  1493  }
  1494  
  1495  func TestAppOrgRemoveApplicationCapabilityFailures(t *testing.T) {
  1496  	t.Parallel()
  1497  
  1498  	tests := []struct {
  1499  		testName         string
  1500  		capability       string
  1501  		applicationGroup func(ag *cb.ConfigGroup)
  1502  		expectedErr      string
  1503  	}{
  1504  		{
  1505  			testName:   "when capability does not exist",
  1506  			capability: "V2_0",
  1507  			applicationGroup: func(ag *cb.ConfigGroup) {
  1508  			},
  1509  			expectedErr: "capability not set",
  1510  		},
  1511  		{
  1512  			testName:   "when retrieving existing capabilities",
  1513  			capability: "V1_3",
  1514  			applicationGroup: func(ag *cb.ConfigGroup) {
  1515  				ag.Values = map[string]*cb.ConfigValue{
  1516  					CapabilitiesKey: {
  1517  						Value: []byte("foobar"),
  1518  					},
  1519  				}
  1520  			},
  1521  			expectedErr: "retrieving application capabilities: unmarshaling capabilities: proto: can't skip unknown wire type 6",
  1522  		},
  1523  	}
  1524  
  1525  	for _, tt := range tests {
  1526  		tt := tt
  1527  		t.Run(tt.testName, func(t *testing.T) {
  1528  			t.Parallel()
  1529  
  1530  			gt := NewGomegaWithT(t)
  1531  
  1532  			baseApp, _ := baseApplication(t)
  1533  			appGroup, err := newApplicationGroupTemplate(baseApp)
  1534  			gt.Expect(err).NotTo(HaveOccurred())
  1535  			tt.applicationGroup(appGroup)
  1536  
  1537  			config := &cb.Config{
  1538  				ChannelGroup: &cb.ConfigGroup{
  1539  					Groups: map[string]*cb.ConfigGroup{
  1540  						ApplicationGroupKey: appGroup,
  1541  					},
  1542  				},
  1543  			}
  1544  
  1545  			c := New(config)
  1546  
  1547  			err = c.Application().RemoveCapability(tt.capability)
  1548  			gt.Expect(err).To(MatchError(tt.expectedErr))
  1549  		})
  1550  	}
  1551  }
  1552  
  1553  func TestApplicationOrg(t *testing.T) {
  1554  	t.Parallel()
  1555  	gt := NewGomegaWithT(t)
  1556  
  1557  	channel := Channel{
  1558  		Consortium: "SampleConsortium",
  1559  		Application: Application{
  1560  			Policies:      standardPolicies(),
  1561  			Organizations: []Organization{baseApplicationOrg(t)},
  1562  		},
  1563  		ModPolicy: AdminsPolicyKey,
  1564  	}
  1565  	channelGroup, err := newChannelGroup(channel)
  1566  	gt.Expect(err).NotTo(HaveOccurred())
  1567  	orgGroup, err := newApplicationOrgConfigGroup(channel.Application.Organizations[0])
  1568  	gt.Expect(err).NotTo(HaveOccurred())
  1569  	channelGroup.Groups[ApplicationGroupKey].Groups["Org1"] = orgGroup
  1570  
  1571  	config := &cb.Config{
  1572  		ChannelGroup: channelGroup,
  1573  	}
  1574  
  1575  	c := New(config)
  1576  
  1577  	expectedOrg := channel.Application.Organizations[0]
  1578  
  1579  	tests := []struct {
  1580  		name    string
  1581  		orgName string
  1582  	}{
  1583  		{
  1584  			name:    "success",
  1585  			orgName: "Org1",
  1586  		},
  1587  	}
  1588  
  1589  	for _, tc := range tests {
  1590  		tc := tc
  1591  		t.Run(tc.name, func(t *testing.T) {
  1592  			t.Parallel()
  1593  			gt := NewGomegaWithT(t)
  1594  
  1595  			org, err := c.Application().Organization(tc.orgName).Configuration()
  1596  			gt.Expect(err).ToNot(HaveOccurred())
  1597  			gt.Expect(expectedOrg).To(Equal(org))
  1598  		})
  1599  	}
  1600  }
  1601  
  1602  func TestAppOrgRemoveApplicationOrg(t *testing.T) {
  1603  	t.Parallel()
  1604  	gt := NewGomegaWithT(t)
  1605  
  1606  	channel := Channel{
  1607  		Consortium: "SampleConsortium",
  1608  		Application: Application{
  1609  			Policies:      standardPolicies(),
  1610  			Organizations: []Organization{baseApplicationOrg(t)},
  1611  		},
  1612  	}
  1613  	channelGroup, err := newChannelGroup(channel)
  1614  	gt.Expect(err).NotTo(HaveOccurred())
  1615  	orgGroup, err := newOrgConfigGroup(channel.Application.Organizations[0])
  1616  	gt.Expect(err).NotTo(HaveOccurred())
  1617  	channelGroup.Groups[ApplicationGroupKey].Groups["Org1"] = orgGroup
  1618  
  1619  	config := &cb.Config{
  1620  		ChannelGroup: channelGroup,
  1621  	}
  1622  
  1623  	c := New(config)
  1624  
  1625  	c.Application().RemoveOrganization("Org1")
  1626  	gt.Expect(c.updated.ChannelGroup.Groups[ApplicationGroupKey].Groups["Org1"]).To(BeNil())
  1627  }
  1628  
  1629  func TestAppOrgRemoveApplicationOrgPolicy(t *testing.T) {
  1630  	t.Parallel()
  1631  	gt := NewGomegaWithT(t)
  1632  
  1633  	channelGroup := newConfigGroup()
  1634  	applicationGroup := newConfigGroup()
  1635  
  1636  	application, _ := baseApplication(t)
  1637  
  1638  	for _, org := range application.Organizations {
  1639  		org.Policies = applicationOrgStandardPolicies()
  1640  		org.Policies["TestPolicy"] = Policy{
  1641  			Type: ImplicitMetaPolicyType,
  1642  			Rule: "MAJORITY Endorsement",
  1643  		}
  1644  		org.ModPolicy = AdminsPolicyKey
  1645  
  1646  		orgGroup, err := newOrgConfigGroup(org)
  1647  		gt.Expect(err).NotTo(HaveOccurred())
  1648  
  1649  		applicationGroup.Groups[org.Name] = orgGroup
  1650  	}
  1651  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1652  	config := &cb.Config{
  1653  		ChannelGroup: channelGroup,
  1654  	}
  1655  
  1656  	c := New(config)
  1657  
  1658  	application.Organizations[0].Policies = applicationOrgStandardPolicies()
  1659  	expectedOrgConfigGroup, _ := newOrgConfigGroup(application.Organizations[0])
  1660  	expectedPolicies := expectedOrgConfigGroup.Policies
  1661  
  1662  	applicationOrg1 := c.Application().Organization("Org1")
  1663  	err := applicationOrg1.RemovePolicy("TestPolicy")
  1664  	gt.Expect(err).NotTo(HaveOccurred())
  1665  
  1666  	actualOrg1Policies := applicationOrg1.orgGroup.Policies
  1667  	gt.Expect(actualOrg1Policies).To(Equal(expectedPolicies))
  1668  }
  1669  
  1670  func TestAppOrgRemoveApplicationOrgPolicyFailures(t *testing.T) {
  1671  	t.Parallel()
  1672  	gt := NewGomegaWithT(t)
  1673  
  1674  	channelGroup := newConfigGroup()
  1675  	applicationGroup := newConfigGroup()
  1676  
  1677  	application, _ := baseApplication(t)
  1678  	for _, org := range application.Organizations {
  1679  		org.Policies = applicationOrgStandardPolicies()
  1680  		orgGroup, err := newOrgConfigGroup(org)
  1681  		gt.Expect(err).NotTo(HaveOccurred())
  1682  		applicationGroup.Groups[org.Name] = orgGroup
  1683  	}
  1684  
  1685  	applicationGroup.Groups["Org1"].Policies["TestPolicy"] = &cb.ConfigPolicy{
  1686  		Policy: &cb.Policy{
  1687  			Type: 15,
  1688  		},
  1689  	}
  1690  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1691  	config := &cb.Config{
  1692  		ChannelGroup: channelGroup,
  1693  	}
  1694  
  1695  	c := New(config)
  1696  
  1697  	err := c.Application().Organization("Org1").RemovePolicy("TestPolicy")
  1698  	gt.Expect(err).To(MatchError("unknown policy type: 15"))
  1699  }
  1700  
  1701  func TestSetApplicationOrgModPolicy(t *testing.T) {
  1702  	t.Parallel()
  1703  	gt := NewGomegaWithT(t)
  1704  
  1705  	channelGroup := newConfigGroup()
  1706  	applicationGroup := newConfigGroup()
  1707  	application, _ := baseApplication(t)
  1708  
  1709  	for _, org := range application.Organizations {
  1710  		orgGroup, err := newOrgConfigGroup(org)
  1711  		gt.Expect(err).NotTo(HaveOccurred())
  1712  
  1713  		applicationGroup.Groups[org.Name] = orgGroup
  1714  	}
  1715  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1716  	config := &cb.Config{
  1717  		ChannelGroup: channelGroup,
  1718  	}
  1719  
  1720  	c := New(config)
  1721  
  1722  	applicationOrg1 := c.Application().Organization("Org1")
  1723  	err := applicationOrg1.SetModPolicy("TestModPolicy")
  1724  	gt.Expect(err).NotTo(HaveOccurred())
  1725  
  1726  	actualModPolicy := applicationOrg1.orgGroup.GetModPolicy()
  1727  	gt.Expect(actualModPolicy).To(Equal("TestModPolicy"))
  1728  }
  1729  
  1730  func TestSetApplicationOrgModPolicyFailures(t *testing.T) {
  1731  	t.Parallel()
  1732  	gt := NewGomegaWithT(t)
  1733  
  1734  	channelGroup := newConfigGroup()
  1735  	applicationGroup := newConfigGroup()
  1736  	application, _ := baseApplication(t)
  1737  
  1738  	for _, org := range application.Organizations {
  1739  		orgGroup, err := newOrgConfigGroup(org)
  1740  		gt.Expect(err).NotTo(HaveOccurred())
  1741  
  1742  		applicationGroup.Groups[org.Name] = orgGroup
  1743  	}
  1744  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1745  	config := &cb.Config{
  1746  		ChannelGroup: channelGroup,
  1747  	}
  1748  
  1749  	c := New(config)
  1750  
  1751  	err := c.Application().Organization("Org1").SetModPolicy("")
  1752  	gt.Expect(err).To(MatchError("non empty mod policy is required"))
  1753  }
  1754  
  1755  func TestSetApplicationOrgPolicy(t *testing.T) {
  1756  	t.Parallel()
  1757  	gt := NewGomegaWithT(t)
  1758  
  1759  	channelGroup := newConfigGroup()
  1760  	applicationGroup := newConfigGroup()
  1761  
  1762  	application, _ := baseApplication(t)
  1763  
  1764  	for _, org := range application.Organizations {
  1765  		org.Policies = applicationOrgStandardPolicies()
  1766  
  1767  		orgGroup, err := newOrgConfigGroup(org)
  1768  		gt.Expect(err).NotTo(HaveOccurred())
  1769  
  1770  		applicationGroup.Groups[org.Name] = orgGroup
  1771  	}
  1772  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1773  	config := &cb.Config{
  1774  		ChannelGroup: channelGroup,
  1775  	}
  1776  
  1777  	c := New(config)
  1778  
  1779  	application.Organizations[0].Policies = applicationOrgStandardPolicies()
  1780  	expectedOrgConfigGroup, _ := newOrgConfigGroup(application.Organizations[0])
  1781  	expectedPolicies := expectedOrgConfigGroup.Policies
  1782  
  1783  	sp, err := policydsl.FromString("OR('Org1MSP.admin', 'Org1MSP.peer','Org1MSP.client')")
  1784  	gt.Expect(err).NotTo(HaveOccurred())
  1785  
  1786  	signaturePolicy, err := proto.Marshal(sp)
  1787  	gt.Expect(err).NotTo(HaveOccurred())
  1788  
  1789  	expectedPolicies["TestPolicy"] = &cb.ConfigPolicy{
  1790  		ModPolicy: AdminsPolicyKey,
  1791  		Policy: &cb.Policy{
  1792  			Type:  int32(cb.Policy_SIGNATURE),
  1793  			Value: signaturePolicy,
  1794  		},
  1795  	}
  1796  
  1797  	applicationOrg1 := c.Application().Organization("Org1")
  1798  	err = applicationOrg1.SetPolicy("TestPolicy", Policy{
  1799  		Type: SignaturePolicyType,
  1800  		Rule: "OR('Org1MSP.admin', 'Org1MSP.peer','Org1MSP.client')",
  1801  	})
  1802  	gt.Expect(err).NotTo(HaveOccurred())
  1803  
  1804  	actualOrg1Policies := applicationOrg1.orgGroup.Policies
  1805  	gt.Expect(err).NotTo(HaveOccurred())
  1806  	gt.Expect(actualOrg1Policies).To(Equal(expectedPolicies))
  1807  }
  1808  
  1809  func TestSetApplicationOrgPolicyFailures(t *testing.T) {
  1810  	t.Parallel()
  1811  	gt := NewGomegaWithT(t)
  1812  
  1813  	channelGroup := newConfigGroup()
  1814  	applicationGroup := newConfigGroup()
  1815  
  1816  	application, _ := baseApplication(t)
  1817  	for _, org := range application.Organizations {
  1818  		org.Policies = applicationOrgStandardPolicies()
  1819  
  1820  		orgGroup, err := newOrgConfigGroup(org)
  1821  		gt.Expect(err).NotTo(HaveOccurred())
  1822  
  1823  		applicationGroup.Groups[org.Name] = orgGroup
  1824  	}
  1825  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1826  	config := &cb.Config{
  1827  		ChannelGroup: channelGroup,
  1828  	}
  1829  
  1830  	c := New(config)
  1831  
  1832  	err := c.Application().Organization("Org1").SetPolicy("TestPolicy", Policy{})
  1833  	gt.Expect(err).To(MatchError("failed to set policy 'TestPolicy': unknown policy type: "))
  1834  }
  1835  
  1836  func TestSetApplicationOrgPolicies(t *testing.T) {
  1837  	t.Parallel()
  1838  	gt := NewGomegaWithT(t)
  1839  
  1840  	channelGroup := newConfigGroup()
  1841  	applicationGroup := newConfigGroup()
  1842  
  1843  	application, _ := baseApplication(t)
  1844  
  1845  	for _, org := range application.Organizations {
  1846  		org.Policies = applicationOrgStandardPolicies()
  1847  		org.Policies["TestPolicy_Remove"] = org.Policies[EndorsementPolicyKey]
  1848  
  1849  		orgGroup, err := newOrgConfigGroup(org)
  1850  		gt.Expect(err).NotTo(HaveOccurred())
  1851  
  1852  		applicationGroup.Groups[org.Name] = orgGroup
  1853  	}
  1854  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1855  	config := &cb.Config{
  1856  		ChannelGroup: channelGroup,
  1857  	}
  1858  
  1859  	c := New(config)
  1860  
  1861  	applicationOrg1 := c.Application().Organization("Org1")
  1862  	policies := map[string]Policy{
  1863  		ReadersPolicyKey: {
  1864  			Type:      ImplicitMetaPolicyType,
  1865  			Rule:      "ANY Readers",
  1866  			ModPolicy: AdminsPolicyKey,
  1867  		},
  1868  		WritersPolicyKey: {
  1869  			Type:      ImplicitMetaPolicyType,
  1870  			Rule:      "ANY Writers",
  1871  			ModPolicy: AdminsPolicyKey,
  1872  		},
  1873  		AdminsPolicyKey: {
  1874  			Type:      ImplicitMetaPolicyType,
  1875  			Rule:      "MAJORITY Admins",
  1876  			ModPolicy: AdminsPolicyKey,
  1877  		},
  1878  		EndorsementPolicyKey: {
  1879  			Type:      ImplicitMetaPolicyType,
  1880  			Rule:      "MAJORITY Endorsement",
  1881  			ModPolicy: AdminsPolicyKey,
  1882  		},
  1883  		LifecycleEndorsementPolicyKey: {
  1884  			Type:      ImplicitMetaPolicyType,
  1885  			Rule:      "MAJORITY Endorsement",
  1886  			ModPolicy: AdminsPolicyKey,
  1887  		},
  1888  		"TestPolicy_Add1": {
  1889  			Type:      ImplicitMetaPolicyType,
  1890  			Rule:      "MAJORITY Endorsement",
  1891  			ModPolicy: AdminsPolicyKey,
  1892  		},
  1893  		"TestPolicy_Add2": {
  1894  			Type:      ImplicitMetaPolicyType,
  1895  			Rule:      "MAJORITY Endorsement",
  1896  			ModPolicy: AdminsPolicyKey,
  1897  		},
  1898  	}
  1899  	err := applicationOrg1.SetPolicies(policies)
  1900  	gt.Expect(err).NotTo(HaveOccurred())
  1901  
  1902  	updatedPolicies, err := applicationOrg1.Policies()
  1903  	gt.Expect(err).NotTo(HaveOccurred())
  1904  	gt.Expect(updatedPolicies).To(Equal(policies))
  1905  
  1906  	originalPolicies := c.original.ChannelGroup.Groups[ApplicationGroupKey].Groups["Org1"].Policies
  1907  	gt.Expect(originalPolicies).To(Equal(applicationGroup.Groups["Org1"].Policies))
  1908  }
  1909  
  1910  func TestSetApplicationOrgPoliciesFailures(t *testing.T) {
  1911  	t.Parallel()
  1912  	gt := NewGomegaWithT(t)
  1913  
  1914  	channelGroup := newConfigGroup()
  1915  	applicationGroup := newConfigGroup()
  1916  
  1917  	application, _ := baseApplication(t)
  1918  	for _, org := range application.Organizations {
  1919  		org.Policies = applicationOrgStandardPolicies()
  1920  
  1921  		orgGroup, err := newOrgConfigGroup(org)
  1922  		gt.Expect(err).NotTo(HaveOccurred())
  1923  
  1924  		applicationGroup.Groups[org.Name] = orgGroup
  1925  	}
  1926  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1927  	config := &cb.Config{
  1928  		ChannelGroup: channelGroup,
  1929  	}
  1930  
  1931  	c := New(config)
  1932  
  1933  	policies := map[string]Policy{
  1934  		ReadersPolicyKey: {
  1935  			Type: ImplicitMetaPolicyType,
  1936  			Rule: "ANY Readers",
  1937  		},
  1938  		WritersPolicyKey: {
  1939  			Type: ImplicitMetaPolicyType,
  1940  			Rule: "ANY Writers",
  1941  		},
  1942  		AdminsPolicyKey: {
  1943  			Type: ImplicitMetaPolicyType,
  1944  			Rule: "MAJORITY Admins",
  1945  		},
  1946  		EndorsementPolicyKey: {
  1947  			Type: ImplicitMetaPolicyType,
  1948  			Rule: "MAJORITY Endorsement",
  1949  		},
  1950  		LifecycleEndorsementPolicyKey: {
  1951  			Type: ImplicitMetaPolicyType,
  1952  			Rule: "MAJORITY Endorsement",
  1953  		},
  1954  		"TestPolicy": {},
  1955  	}
  1956  
  1957  	err := c.Application().Organization("Org1").SetPolicies(policies)
  1958  	gt.Expect(err).To(MatchError("failed to set policies: unknown policy type: "))
  1959  }
  1960  
  1961  func TestSetApplicationModPolicy(t *testing.T) {
  1962  	t.Parallel()
  1963  	gt := NewGomegaWithT(t)
  1964  
  1965  	channelGroup := newConfigGroup()
  1966  	application, _ := baseApplication(t)
  1967  
  1968  	applicationGroup, err := newApplicationGroupTemplate(application)
  1969  	gt.Expect(err).NotTo(HaveOccurred())
  1970  
  1971  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1972  	config := &cb.Config{
  1973  		ChannelGroup: channelGroup,
  1974  	}
  1975  
  1976  	c := New(config)
  1977  
  1978  	a := c.Application()
  1979  	err = a.SetModPolicy("TestModPolicy")
  1980  	gt.Expect(err).NotTo(HaveOccurred())
  1981  
  1982  	updatedModPolicy := a.applicationGroup.GetModPolicy()
  1983  	gt.Expect(updatedModPolicy).To(Equal("TestModPolicy"))
  1984  }
  1985  
  1986  func TestSetApplicationModPolicyFailures(t *testing.T) {
  1987  	t.Parallel()
  1988  	gt := NewGomegaWithT(t)
  1989  
  1990  	channelGroup := newConfigGroup()
  1991  	application, _ := baseApplication(t)
  1992  
  1993  	applicationGroup, err := newApplicationGroupTemplate(application)
  1994  	gt.Expect(err).NotTo(HaveOccurred())
  1995  
  1996  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  1997  	config := &cb.Config{
  1998  		ChannelGroup: channelGroup,
  1999  	}
  2000  
  2001  	c := New(config)
  2002  
  2003  	err = c.Application().SetModPolicy("")
  2004  	gt.Expect(err).To(MatchError("non empty mod policy is required"))
  2005  }
  2006  
  2007  func TestSetApplicationPolicy(t *testing.T) {
  2008  	t.Parallel()
  2009  	gt := NewGomegaWithT(t)
  2010  
  2011  	channelGroup := newConfigGroup()
  2012  	application, _ := baseApplication(t)
  2013  
  2014  	applicationGroup, err := newApplicationGroupTemplate(application)
  2015  	gt.Expect(err).NotTo(HaveOccurred())
  2016  
  2017  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  2018  	config := &cb.Config{
  2019  		ChannelGroup: channelGroup,
  2020  	}
  2021  
  2022  	c := New(config)
  2023  
  2024  	expectedPolicies := map[string]Policy{
  2025  		ReadersPolicyKey: {
  2026  			Type:      ImplicitMetaPolicyType,
  2027  			Rule:      "ANY Readers",
  2028  			ModPolicy: AdminsPolicyKey,
  2029  		},
  2030  		WritersPolicyKey: {
  2031  			Type:      ImplicitMetaPolicyType,
  2032  			Rule:      "ANY Writers",
  2033  			ModPolicy: AdminsPolicyKey,
  2034  		},
  2035  		AdminsPolicyKey: {
  2036  			Type:      ImplicitMetaPolicyType,
  2037  			Rule:      "MAJORITY Admins",
  2038  			ModPolicy: AdminsPolicyKey,
  2039  		},
  2040  		"TestPolicy": {
  2041  			Type:      ImplicitMetaPolicyType,
  2042  			Rule:      "MAJORITY Endorsement",
  2043  			ModPolicy: AdminsPolicyKey,
  2044  		},
  2045  	}
  2046  
  2047  	a := c.Application()
  2048  	err = a.SetPolicy("TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "MAJORITY Endorsement"})
  2049  	gt.Expect(err).NotTo(HaveOccurred())
  2050  
  2051  	updatedPolicies, err := a.Policies()
  2052  	gt.Expect(err).NotTo(HaveOccurred())
  2053  	gt.Expect(updatedPolicies).To(Equal(expectedPolicies))
  2054  }
  2055  
  2056  func TestSetApplicationPolicyFailures(t *testing.T) {
  2057  	t.Parallel()
  2058  	gt := NewGomegaWithT(t)
  2059  
  2060  	channelGroup := newConfigGroup()
  2061  	application, _ := baseApplication(t)
  2062  
  2063  	applicationGroup, err := newApplicationGroupTemplate(application)
  2064  	gt.Expect(err).NotTo(HaveOccurred())
  2065  
  2066  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  2067  	config := &cb.Config{
  2068  		ChannelGroup: channelGroup,
  2069  	}
  2070  
  2071  	c := New(config)
  2072  
  2073  	expectedPolicies := application.Policies
  2074  	expectedPolicies["TestPolicy"] = expectedPolicies[EndorsementPolicyKey]
  2075  
  2076  	err = c.Application().SetPolicy("TestPolicy", Policy{})
  2077  	gt.Expect(err).To(MatchError("failed to set policy 'TestPolicy': unknown policy type: "))
  2078  }
  2079  
  2080  func TestSetApplicationPolicies(t *testing.T) {
  2081  	t.Parallel()
  2082  	gt := NewGomegaWithT(t)
  2083  
  2084  	channelGroup := newConfigGroup()
  2085  	application, _ := baseApplication(t)
  2086  	application.Policies["TestPolicy_Remove"] = application.Policies[ReadersPolicyKey]
  2087  
  2088  	applicationGroup, err := newApplicationGroupTemplate(application)
  2089  	gt.Expect(err).NotTo(HaveOccurred())
  2090  
  2091  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  2092  	config := &cb.Config{
  2093  		ChannelGroup: channelGroup,
  2094  	}
  2095  
  2096  	c := New(config)
  2097  
  2098  	newPolicies := map[string]Policy{
  2099  		ReadersPolicyKey: {
  2100  			Type:      ImplicitMetaPolicyType,
  2101  			Rule:      "ANY Readers",
  2102  			ModPolicy: AdminsPolicyKey,
  2103  		},
  2104  		WritersPolicyKey: {
  2105  			Type:      ImplicitMetaPolicyType,
  2106  			Rule:      "ANY Writers",
  2107  			ModPolicy: AdminsPolicyKey,
  2108  		},
  2109  		AdminsPolicyKey: {
  2110  			Type:      ImplicitMetaPolicyType,
  2111  			Rule:      "MAJORITY Admins",
  2112  			ModPolicy: AdminsPolicyKey,
  2113  		},
  2114  		"TestPolicy_Add1": {
  2115  			Type:      ImplicitMetaPolicyType,
  2116  			Rule:      "MAJORITY Endorsement",
  2117  			ModPolicy: AdminsPolicyKey,
  2118  		},
  2119  		"TestPolicy_Add2": {
  2120  			Type:      ImplicitMetaPolicyType,
  2121  			Rule:      "MAJORITY Endorsement",
  2122  			ModPolicy: AdminsPolicyKey,
  2123  		},
  2124  	}
  2125  
  2126  	a := c.Application()
  2127  	err = a.SetPolicies(newPolicies)
  2128  	gt.Expect(err).NotTo(HaveOccurred())
  2129  
  2130  	updatedPolicies, err := a.Policies()
  2131  	gt.Expect(err).NotTo(HaveOccurred())
  2132  	gt.Expect(updatedPolicies).To(Equal(newPolicies))
  2133  
  2134  	originalPolicies := c.original.ChannelGroup.Groups[ApplicationGroupKey].Policies
  2135  	gt.Expect(originalPolicies).To(Equal(applicationGroup.Policies))
  2136  }
  2137  
  2138  func TestSetApplicationPoliciesFailures(t *testing.T) {
  2139  	t.Parallel()
  2140  	gt := NewGomegaWithT(t)
  2141  
  2142  	channelGroup := newConfigGroup()
  2143  	application, _ := baseApplication(t)
  2144  
  2145  	applicationGroup, err := newApplicationGroupTemplate(application)
  2146  	gt.Expect(err).NotTo(HaveOccurred())
  2147  
  2148  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  2149  	config := &cb.Config{
  2150  		ChannelGroup: channelGroup,
  2151  	}
  2152  
  2153  	c := New(config)
  2154  
  2155  	newPolicies := map[string]Policy{
  2156  		ReadersPolicyKey: {
  2157  			Type: ImplicitMetaPolicyType,
  2158  			Rule: "ANY Readers",
  2159  		},
  2160  		WritersPolicyKey: {
  2161  			Type: ImplicitMetaPolicyType,
  2162  			Rule: "ANY Writers",
  2163  		},
  2164  		AdminsPolicyKey: {
  2165  			Type: ImplicitMetaPolicyType,
  2166  			Rule: "MAJORITY Admins",
  2167  		},
  2168  		"TestPolicy": {},
  2169  	}
  2170  
  2171  	err = c.Application().SetPolicies(newPolicies)
  2172  	gt.Expect(err).To(MatchError("failed to set policies: unknown policy type: "))
  2173  }
  2174  
  2175  func TestAppOrgRemoveApplicationPolicy(t *testing.T) {
  2176  	t.Parallel()
  2177  	gt := NewGomegaWithT(t)
  2178  
  2179  	channelGroup := newConfigGroup()
  2180  	application, _ := baseApplication(t)
  2181  
  2182  	applicationGroup, err := newApplicationGroupTemplate(application)
  2183  	gt.Expect(err).NotTo(HaveOccurred())
  2184  	applicationGroup.Policies["TestPolicy"] = applicationGroup.Policies[AdminsPolicyKey]
  2185  
  2186  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  2187  	config := &cb.Config{
  2188  		ChannelGroup: channelGroup,
  2189  	}
  2190  
  2191  	c := New(config)
  2192  
  2193  	expectedPolicies := map[string]Policy{
  2194  		ReadersPolicyKey: {
  2195  			Type:      ImplicitMetaPolicyType,
  2196  			Rule:      "ANY Readers",
  2197  			ModPolicy: AdminsPolicyKey,
  2198  		},
  2199  		WritersPolicyKey: {
  2200  			Type:      ImplicitMetaPolicyType,
  2201  			Rule:      "ANY Writers",
  2202  			ModPolicy: AdminsPolicyKey,
  2203  		},
  2204  		AdminsPolicyKey: {
  2205  			Type:      ImplicitMetaPolicyType,
  2206  			Rule:      "MAJORITY Admins",
  2207  			ModPolicy: AdminsPolicyKey,
  2208  		},
  2209  	}
  2210  
  2211  	a := c.Application()
  2212  	err = a.RemovePolicy("TestPolicy")
  2213  	gt.Expect(err).NotTo(HaveOccurred())
  2214  
  2215  	updatedPolicies, err := a.Policies()
  2216  	gt.Expect(err).NotTo(HaveOccurred())
  2217  	gt.Expect(updatedPolicies).To(Equal(expectedPolicies))
  2218  }
  2219  
  2220  func TestAppOrgRemoveApplicationPolicyFailures(t *testing.T) {
  2221  	t.Parallel()
  2222  	gt := NewGomegaWithT(t)
  2223  
  2224  	channelGroup := newConfigGroup()
  2225  	application, _ := baseApplication(t)
  2226  
  2227  	applicationGroup, err := newApplicationGroupTemplate(application)
  2228  	gt.Expect(err).NotTo(HaveOccurred())
  2229  
  2230  	applicationGroup.Policies[EndorsementPolicyKey] = &cb.ConfigPolicy{
  2231  		Policy: &cb.Policy{
  2232  			Type: 15,
  2233  		},
  2234  	}
  2235  	channelGroup.Groups[ApplicationGroupKey] = applicationGroup
  2236  
  2237  	config := &cb.Config{
  2238  		ChannelGroup: channelGroup,
  2239  	}
  2240  
  2241  	c := New(config)
  2242  
  2243  	err = c.Application().RemovePolicy("TestPolicy")
  2244  	gt.Expect(err).To(MatchError("unknown policy type: 15"))
  2245  }
  2246  
  2247  func TestApplicationMSP(t *testing.T) {
  2248  	t.Parallel()
  2249  
  2250  	gt := NewGomegaWithT(t)
  2251  
  2252  	application, _ := baseApplication(t)
  2253  	applicationGroup, err := newApplicationGroup(application)
  2254  	gt.Expect(err).NotTo(HaveOccurred())
  2255  
  2256  	config := &cb.Config{
  2257  		ChannelGroup: &cb.ConfigGroup{
  2258  			Groups: map[string]*cb.ConfigGroup{
  2259  				ApplicationGroupKey: applicationGroup,
  2260  			},
  2261  		},
  2262  	}
  2263  
  2264  	c := New(config)
  2265  
  2266  	msp, err := c.Application().Organization("Org1").MSP().Configuration()
  2267  	gt.Expect(err).NotTo(HaveOccurred())
  2268  	gt.Expect(msp).To(Equal(application.Organizations[0].MSP))
  2269  }
  2270  
  2271  func TestSetApplicationMSPFailure(t *testing.T) {
  2272  	t.Parallel()
  2273  
  2274  	tests := []struct {
  2275  		spec        string
  2276  		mspMod      func(MSP) MSP
  2277  		orgName     string
  2278  		expectedErr string
  2279  	}{
  2280  		{
  2281  			spec: "updating msp name",
  2282  			mspMod: func(msp MSP) MSP {
  2283  				msp.Name = "thiscantbegood"
  2284  				return msp
  2285  			},
  2286  			orgName:     "Org1",
  2287  			expectedErr: "MSP name cannot be changed",
  2288  		},
  2289  		{
  2290  			spec: "invalid root ca cert keyusage",
  2291  			mspMod: func(msp MSP) MSP {
  2292  				msp.RootCerts = []*x509.Certificate{
  2293  					{
  2294  						SerialNumber: big.NewInt(7),
  2295  						KeyUsage:     x509.KeyUsageKeyAgreement,
  2296  					},
  2297  				}
  2298  				return msp
  2299  			},
  2300  			orgName:     "Org1",
  2301  			expectedErr: "invalid root cert: KeyUsage must be x509.KeyUsageCertSign. serial number: 7",
  2302  		},
  2303  		{
  2304  			spec: "root ca cert is not a ca",
  2305  			mspMod: func(msp MSP) MSP {
  2306  				msp.RootCerts = []*x509.Certificate{
  2307  					{
  2308  						SerialNumber: big.NewInt(7),
  2309  						KeyUsage:     x509.KeyUsageCertSign,
  2310  						IsCA:         false,
  2311  					},
  2312  				}
  2313  				return msp
  2314  			},
  2315  			orgName:     "Org1",
  2316  			expectedErr: "invalid root cert: must be a CA certificate. serial number: 7",
  2317  		},
  2318  		{
  2319  			spec: "invalid intermediate ca keyusage",
  2320  			mspMod: func(msp MSP) MSP {
  2321  				msp.IntermediateCerts = []*x509.Certificate{
  2322  					{
  2323  						SerialNumber: big.NewInt(7),
  2324  						KeyUsage:     x509.KeyUsageKeyAgreement,
  2325  					},
  2326  				}
  2327  				return msp
  2328  			},
  2329  			orgName:     "Org1",
  2330  			expectedErr: "invalid intermediate cert: KeyUsage must be x509.KeyUsageCertSign. serial number: 7",
  2331  		},
  2332  		{
  2333  			spec: "invalid intermediate cert -- not signed by root cert",
  2334  			mspMod: func(msp MSP) MSP {
  2335  				cert, _ := generateCACertAndPrivateKey(t, "org1.example.com")
  2336  				cert.SerialNumber = big.NewInt(7)
  2337  				msp.IntermediateCerts = []*x509.Certificate{cert}
  2338  				return msp
  2339  			},
  2340  			orgName:     "Org1",
  2341  			expectedErr: "intermediate cert not signed by any root certs of this MSP. serial number: 7",
  2342  		},
  2343  		{
  2344  			spec: "tls root ca cert is not a ca",
  2345  			mspMod: func(msp MSP) MSP {
  2346  				msp.TLSRootCerts = []*x509.Certificate{
  2347  					{
  2348  						SerialNumber: big.NewInt(7),
  2349  						KeyUsage:     x509.KeyUsageCertSign,
  2350  						IsCA:         false,
  2351  					},
  2352  				}
  2353  				return msp
  2354  			},
  2355  			orgName:     "Org1",
  2356  			expectedErr: "invalid tls root cert: must be a CA certificate. serial number: 7",
  2357  		},
  2358  		{
  2359  			spec: "tls intemediate ca cert is not a ca",
  2360  			mspMod: func(msp MSP) MSP {
  2361  				msp.TLSIntermediateCerts = []*x509.Certificate{
  2362  					{
  2363  						SerialNumber: big.NewInt(7),
  2364  						KeyUsage:     x509.KeyUsageCertSign,
  2365  						IsCA:         false,
  2366  					},
  2367  				}
  2368  				return msp
  2369  			},
  2370  			orgName:     "Org1",
  2371  			expectedErr: "invalid tls intermediate cert: must be a CA certificate. serial number: 7",
  2372  		},
  2373  	}
  2374  
  2375  	for _, tc := range tests {
  2376  		tc := tc
  2377  		t.Run(tc.spec, func(t *testing.T) {
  2378  			t.Parallel()
  2379  			gt := NewGomegaWithT(t)
  2380  			channelGroup, _, err := baseApplicationChannelGroup(t)
  2381  			gt.Expect(err).ToNot(HaveOccurred())
  2382  			config := &cb.Config{
  2383  				ChannelGroup: channelGroup,
  2384  			}
  2385  
  2386  			c := New(config)
  2387  
  2388  			org1MSP, err := c.Application().Organization("Org1").MSP().Configuration()
  2389  			gt.Expect(err).NotTo(HaveOccurred())
  2390  
  2391  			org1MSP = tc.mspMod(org1MSP)
  2392  			err = c.Application().Organization(tc.orgName).SetMSP(org1MSP)
  2393  			gt.Expect(err).To(MatchError(tc.expectedErr))
  2394  		})
  2395  	}
  2396  }
  2397  
  2398  func TestSetApplicationMSP(t *testing.T) {
  2399  	t.Parallel()
  2400  	gt := NewGomegaWithT(t)
  2401  
  2402  	channelGroup, privateKeys, err := baseApplicationChannelGroup(t)
  2403  	gt.Expect(err).ToNot(HaveOccurred())
  2404  	config := &cb.Config{
  2405  		ChannelGroup: channelGroup,
  2406  	}
  2407  
  2408  	c := New(config)
  2409  
  2410  	org1MSP, err := c.Application().Organization("Org1").MSP().Configuration()
  2411  	gt.Expect(err).NotTo(HaveOccurred())
  2412  	org2MSP, err := c.Application().Organization("Org2").MSP().Configuration()
  2413  	gt.Expect(err).NotTo(HaveOccurred())
  2414  	org1CertBase64, org1CRLBase64 := certCRLBase64(t, org1MSP)
  2415  	org2CertBase64, org2CRLBase64 := certCRLBase64(t, org2MSP)
  2416  
  2417  	newRootCert, newRootPrivKey := generateCACertAndPrivateKey(t, "anotherca-org1.example.com")
  2418  	newRootCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(newRootCert))
  2419  	org1MSP.RootCerts = append(org1MSP.RootCerts, newRootCert)
  2420  
  2421  	newIntermediateCert, _ := generateIntermediateCACertAndPrivateKey(t, "anotherca-org1.example.com", newRootCert, newRootPrivKey)
  2422  	newIntermediateCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(newIntermediateCert))
  2423  	org1MSP.IntermediateCerts = append(org1MSP.IntermediateCerts, newIntermediateCert)
  2424  
  2425  	cert := org1MSP.RootCerts[0]
  2426  	privKey := privateKeys[0]
  2427  	certToRevoke, _ := generateCertAndPrivateKeyFromCACert(t, "org1.example.com", cert, privKey)
  2428  	signingIdentity := &SigningIdentity{
  2429  		Certificate: cert,
  2430  		PrivateKey:  privKey,
  2431  		MSPID:       "MSPID",
  2432  	}
  2433  	newCRL, err := org1MSP.CreateMSPCRL(signingIdentity, certToRevoke)
  2434  	gt.Expect(err).NotTo(HaveOccurred())
  2435  	pemNewCRL, err := pemEncodeCRL(newCRL)
  2436  	gt.Expect(err).NotTo(HaveOccurred())
  2437  	newCRLBase64 := base64.StdEncoding.EncodeToString(pemNewCRL)
  2438  	org1MSP.RevocationList = append(org1MSP.RevocationList, newCRL)
  2439  
  2440  	err = c.Application().Organization("Org1").SetMSP(org1MSP)
  2441  	gt.Expect(err).NotTo(HaveOccurred())
  2442  
  2443  	expectedConfigJSON := fmt.Sprintf(`
  2444  {
  2445  	"channel_group": {
  2446  		"groups": {
  2447  			"Application": {
  2448  				"groups": {
  2449  					"Org1": {
  2450  						"groups": {},
  2451  						"mod_policy": "Admins",
  2452  						"policies": {
  2453  							"Admins": {
  2454  								"mod_policy": "Admins",
  2455  								"policy": {
  2456  									"type": 3,
  2457  									"value": {
  2458  										"rule": "MAJORITY",
  2459  										"sub_policy": "Admins"
  2460  									}
  2461  								},
  2462  								"version": "0"
  2463  							},
  2464  							"Endorsement": {
  2465  								"mod_policy": "Admins",
  2466  								"policy": {
  2467  									"type": 3,
  2468  									"value": {
  2469  										"rule": "MAJORITY",
  2470  										"sub_policy": "Endorsement"
  2471  									}
  2472  								},
  2473  								"version": "0"
  2474  							},
  2475  							"LifecycleEndorsement": {
  2476  								"mod_policy": "Admins",
  2477  								"policy": {
  2478  									"type": 3,
  2479  									"value": {
  2480  										"rule": "MAJORITY",
  2481  										"sub_policy": "Endorsement"
  2482  									}
  2483  								},
  2484  								"version": "0"
  2485  							},
  2486  							"Readers": {
  2487  								"mod_policy": "Admins",
  2488  								"policy": {
  2489  									"type": 3,
  2490  									"value": {
  2491  										"rule": "ANY",
  2492  										"sub_policy": "Readers"
  2493  									}
  2494  								},
  2495  								"version": "0"
  2496  							},
  2497  							"Writers": {
  2498  								"mod_policy": "Admins",
  2499  								"policy": {
  2500  									"type": 3,
  2501  									"value": {
  2502  										"rule": "ANY",
  2503  										"sub_policy": "Writers"
  2504  									}
  2505  								},
  2506  								"version": "0"
  2507  							}
  2508  						},
  2509  						"values": {
  2510  							"MSP": {
  2511  								"mod_policy": "Admins",
  2512  								"value": {
  2513  									"config": {
  2514  										"admins": [
  2515  											"%[1]s"
  2516  										],
  2517  										"crypto_config": {
  2518  											"identity_identifier_hash_function": "SHA256",
  2519  											"signature_hash_family": "SHA3"
  2520  										},
  2521  										"fabric_node_ous": {
  2522  											"admin_ou_identifier": {
  2523  												"certificate": "%[1]s",
  2524  												"organizational_unit_identifier": "OUID"
  2525  											},
  2526  											"client_ou_identifier": {
  2527  												"certificate": "%[1]s",
  2528  												"organizational_unit_identifier": "OUID"
  2529  											},
  2530  											"enable": false,
  2531  											"orderer_ou_identifier": {
  2532  												"certificate": "%[1]s",
  2533  												"organizational_unit_identifier": "OUID"
  2534  											},
  2535  											"peer_ou_identifier": {
  2536  												"certificate": "%[1]s",
  2537  												"organizational_unit_identifier": "OUID"
  2538  											}
  2539  										},
  2540  										"intermediate_certs": [
  2541  											"%[1]s",
  2542  											"%[2]s"
  2543  										],
  2544  										"name": "MSPID",
  2545  										"organizational_unit_identifiers": [
  2546  											{
  2547  												"certificate": "%[1]s",
  2548  												"organizational_unit_identifier": "OUID"
  2549  											}
  2550  										],
  2551  										"revocation_list": [
  2552  											"%[3]s",
  2553  											"%[4]s"
  2554  										],
  2555  										"root_certs": [
  2556  											"%[1]s",
  2557  											"%[5]s"
  2558  										],
  2559  										"signing_identity": null,
  2560  										"tls_intermediate_certs": [
  2561  											"%[1]s"
  2562  										],
  2563  										"tls_root_certs": [
  2564  											"%[1]s"
  2565  										]
  2566  									},
  2567  									"type": 0
  2568  								},
  2569  								"version": "0"
  2570  							}
  2571  						},
  2572  						"version": "0"
  2573  					},
  2574  					"Org2": {
  2575  						"groups": {},
  2576  						"mod_policy": "Admins",
  2577  						"policies": {
  2578  							"Admins": {
  2579  								"mod_policy": "Admins",
  2580  								"policy": {
  2581  									"type": 3,
  2582  									"value": {
  2583  										"rule": "MAJORITY",
  2584  										"sub_policy": "Admins"
  2585  									}
  2586  								},
  2587  								"version": "0"
  2588  							},
  2589  							"Endorsement": {
  2590  								"mod_policy": "Admins",
  2591  								"policy": {
  2592  									"type": 3,
  2593  									"value": {
  2594  										"rule": "MAJORITY",
  2595  										"sub_policy": "Endorsement"
  2596  									}
  2597  								},
  2598  								"version": "0"
  2599  							},
  2600  							"LifecycleEndorsement": {
  2601  								"mod_policy": "Admins",
  2602  								"policy": {
  2603  									"type": 3,
  2604  									"value": {
  2605  										"rule": "MAJORITY",
  2606  										"sub_policy": "Endorsement"
  2607  									}
  2608  								},
  2609  								"version": "0"
  2610  							},
  2611  							"Readers": {
  2612  								"mod_policy": "Admins",
  2613  								"policy": {
  2614  									"type": 3,
  2615  									"value": {
  2616  										"rule": "ANY",
  2617  										"sub_policy": "Readers"
  2618  									}
  2619  								},
  2620  								"version": "0"
  2621  							},
  2622  							"Writers": {
  2623  								"mod_policy": "Admins",
  2624  								"policy": {
  2625  									"type": 3,
  2626  									"value": {
  2627  										"rule": "ANY",
  2628  										"sub_policy": "Writers"
  2629  									}
  2630  								},
  2631  								"version": "0"
  2632  							}
  2633  						},
  2634  						"values": {
  2635  							"MSP": {
  2636  								"mod_policy": "Admins",
  2637  								"value": {
  2638  									"config": {
  2639  										"admins": [
  2640  											"%[6]s"
  2641  										],
  2642  										"crypto_config": {
  2643  											"identity_identifier_hash_function": "SHA256",
  2644  											"signature_hash_family": "SHA3"
  2645  										},
  2646  										"fabric_node_ous": {
  2647  											"admin_ou_identifier": {
  2648  												"certificate": "%[6]s",
  2649  												"organizational_unit_identifier": "OUID"
  2650  											},
  2651  											"client_ou_identifier": {
  2652  												"certificate": "%[6]s",
  2653  												"organizational_unit_identifier": "OUID"
  2654  											},
  2655  											"enable": false,
  2656  											"orderer_ou_identifier": {
  2657  												"certificate": "%[6]s",
  2658  												"organizational_unit_identifier": "OUID"
  2659  											},
  2660  											"peer_ou_identifier": {
  2661  												"certificate": "%[6]s",
  2662  												"organizational_unit_identifier": "OUID"
  2663  											}
  2664  										},
  2665  										"intermediate_certs": [
  2666  											"%[6]s"
  2667  										],
  2668  										"name": "MSPID",
  2669  										"organizational_unit_identifiers": [
  2670  											{
  2671  												"certificate": "%[6]s",
  2672  												"organizational_unit_identifier": "OUID"
  2673  											}
  2674  										],
  2675  										"revocation_list": [
  2676  											"%[7]s"
  2677  										],
  2678  										"root_certs": [
  2679  											"%[6]s"
  2680  										],
  2681  										"signing_identity": null,
  2682  										"tls_intermediate_certs": [
  2683  											"%[6]s"
  2684  										],
  2685  										"tls_root_certs": [
  2686  											"%[6]s"
  2687  										]
  2688  									},
  2689  									"type": 0
  2690  								},
  2691  								"version": "0"
  2692  							}
  2693  						},
  2694  						"version": "0"
  2695  					}
  2696  				},
  2697  				"mod_policy": "Admins",
  2698  				"policies": {
  2699  					"Admins": {
  2700  						"mod_policy": "Admins",
  2701  						"policy": {
  2702  							"type": 3,
  2703  							"value": {
  2704  								"rule": "MAJORITY",
  2705  								"sub_policy": "Admins"
  2706  							}
  2707  						},
  2708  						"version": "0"
  2709  					},
  2710  					"Readers": {
  2711  						"mod_policy": "Admins",
  2712  						"policy": {
  2713  							"type": 3,
  2714  							"value": {
  2715  								"rule": "ANY",
  2716  								"sub_policy": "Readers"
  2717  							}
  2718  						},
  2719  						"version": "0"
  2720  					},
  2721  					"Writers": {
  2722  						"mod_policy": "Admins",
  2723  						"policy": {
  2724  							"type": 3,
  2725  							"value": {
  2726  								"rule": "ANY",
  2727  								"sub_policy": "Writers"
  2728  							}
  2729  						},
  2730  						"version": "0"
  2731  					}
  2732  				},
  2733  				"values": {
  2734  					"ACLs": {
  2735  						"mod_policy": "Admins",
  2736  						"value": {
  2737  							"acls": {
  2738  								"acl1": {
  2739  									"policy_ref": "hi"
  2740  								}
  2741  							}
  2742  						},
  2743  						"version": "0"
  2744  					},
  2745  					"Capabilities": {
  2746  						"mod_policy": "Admins",
  2747  						"value": {
  2748  							"capabilities": {
  2749  								"V1_3": {}
  2750  							}
  2751  						},
  2752  						"version": "0"
  2753  					}
  2754  				},
  2755  				"version": "0"
  2756  			}
  2757  		},
  2758  		"mod_policy": "",
  2759  		"policies": {},
  2760  		"values": {},
  2761  		"version": "0"
  2762  	},
  2763  	"sequence": "0"
  2764  }
  2765  `, org1CertBase64, newIntermediateCertBase64, org1CRLBase64, newCRLBase64, newRootCertBase64, org2CertBase64, org2CRLBase64)
  2766  
  2767  	buf := bytes.Buffer{}
  2768  	err = protolator.DeepMarshalJSON(&buf, c.updated)
  2769  	gt.Expect(err).NotTo(HaveOccurred())
  2770  
  2771  	gt.Expect(buf.String()).To(MatchJSON(expectedConfigJSON))
  2772  }
  2773  
  2774  func baseApplication(t *testing.T) (Application, []*ecdsa.PrivateKey) {
  2775  	org1BaseMSP, org1PrivKey := baseMSP(t)
  2776  	org2BaseMSP, org2PrivKey := baseMSP(t)
  2777  	return Application{
  2778  		Policies: standardPolicies(),
  2779  		Organizations: []Organization{
  2780  			{
  2781  				Name:     "Org1",
  2782  				Policies: applicationOrgStandardPolicies(),
  2783  				MSP:      org1BaseMSP,
  2784  			},
  2785  			{
  2786  				Name:     "Org2",
  2787  				Policies: applicationOrgStandardPolicies(),
  2788  				MSP:      org2BaseMSP,
  2789  			},
  2790  		},
  2791  		Capabilities: []string{
  2792  			"V1_3",
  2793  		},
  2794  		ACLs: map[string]string{
  2795  			"acl1": "hi",
  2796  		},
  2797  		ModPolicy: AdminsPolicyKey,
  2798  	}, []*ecdsa.PrivateKey{org1PrivKey, org2PrivKey}
  2799  }