github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/interfaces/builtin/location_control_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package builtin_test
    21  
    22  import (
    23  	. "gopkg.in/check.v1"
    24  
    25  	"github.com/snapcore/snapd/interfaces"
    26  	"github.com/snapcore/snapd/interfaces/apparmor"
    27  	"github.com/snapcore/snapd/interfaces/builtin"
    28  	"github.com/snapcore/snapd/snap"
    29  	"github.com/snapcore/snapd/snap/snaptest"
    30  	"github.com/snapcore/snapd/testutil"
    31  )
    32  
    33  type LocationControlInterfaceSuite struct {
    34  	iface    interfaces.Interface
    35  	slotInfo *snap.SlotInfo
    36  	slot     *interfaces.ConnectedSlot
    37  	plugInfo *snap.PlugInfo
    38  	plug     *interfaces.ConnectedPlug
    39  }
    40  
    41  var _ = Suite(&LocationControlInterfaceSuite{
    42  	iface: builtin.MustInterface("location-control"),
    43  })
    44  
    45  func (s *LocationControlInterfaceSuite) SetUpTest(c *C) {
    46  	var plugSnapInfoYaml = `name: location-consumer
    47  version: 1.0
    48  plugs:
    49   location-client:
    50    interface: location-control
    51  apps:
    52   app:
    53    command: foo
    54    plugs: [location-client]
    55  `
    56  	var slotSnapInfoYaml = `name: location
    57  version: 1.0
    58  slots:
    59   location:
    60    interface: location-control
    61  apps:
    62   app2:
    63    command: foo
    64    slots: [location]
    65  `
    66  	snapInfo := snaptest.MockInfo(c, plugSnapInfoYaml, nil)
    67  	s.plugInfo = snapInfo.Plugs["location-client"]
    68  	s.plug = interfaces.NewConnectedPlug(s.plugInfo, nil, nil)
    69  	snapInfo = snaptest.MockInfo(c, slotSnapInfoYaml, nil)
    70  	s.slotInfo = snapInfo.Slots["location"]
    71  	s.slot = interfaces.NewConnectedSlot(s.slotInfo, nil, nil)
    72  }
    73  
    74  func (s *LocationControlInterfaceSuite) TestName(c *C) {
    75  	c.Assert(s.iface.Name(), Equals, "location-control")
    76  }
    77  
    78  // The label glob when all apps are bound to the location slot
    79  func (s *LocationControlInterfaceSuite) TestConnectedPlugSnippetUsesSlotLabelAll(c *C) {
    80  	app1 := &snap.AppInfo{Name: "app1"}
    81  	app2 := &snap.AppInfo{Name: "app2"}
    82  	slot := interfaces.NewConnectedSlot(&snap.SlotInfo{
    83  		Snap: &snap.Info{
    84  			SuggestedName: "location",
    85  			Apps:          map[string]*snap.AppInfo{"app1": app1, "app2": app2},
    86  		},
    87  		Name:      "location",
    88  		Interface: "location",
    89  		Apps:      map[string]*snap.AppInfo{"app1": app1, "app2": app2},
    90  	}, nil, nil)
    91  
    92  	apparmorSpec := &apparmor.Specification{}
    93  	err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, slot)
    94  	c.Assert(err, IsNil)
    95  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.location-consumer.app"})
    96  	c.Assert(apparmorSpec.SnippetForTag("snap.location-consumer.app"), testutil.Contains, `peer=(label="snap.location.*"),`)
    97  }
    98  
    99  // The label uses alternation when some, but not all, apps is bound to the location slot
   100  func (s *LocationControlInterfaceSuite) TestConnectedPlugSnippetUsesSlotLabelSome(c *C) {
   101  	app1 := &snap.AppInfo{Name: "app1"}
   102  	app2 := &snap.AppInfo{Name: "app2"}
   103  	app3 := &snap.AppInfo{Name: "app3"}
   104  	slot := interfaces.NewConnectedSlot(&snap.SlotInfo{
   105  		Snap: &snap.Info{
   106  			SuggestedName: "location",
   107  			Apps:          map[string]*snap.AppInfo{"app1": app1, "app2": app2, "app3": app3},
   108  		},
   109  		Name:      "location",
   110  		Interface: "location",
   111  		Apps:      map[string]*snap.AppInfo{"app1": app1, "app2": app2},
   112  	}, nil, nil)
   113  
   114  	apparmorSpec := &apparmor.Specification{}
   115  	err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, slot)
   116  	c.Assert(err, IsNil)
   117  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.location-consumer.app"})
   118  	c.Assert(apparmorSpec.SnippetForTag("snap.location-consumer.app"), testutil.Contains, `peer=(label="snap.location.{app1,app2}"),`)
   119  }
   120  
   121  // The label uses short form when exactly one app is bound to the location slot
   122  func (s *LocationControlInterfaceSuite) TestConnectedPlugSnippetUsesSlotLabelOne(c *C) {
   123  	app := &snap.AppInfo{Name: "app"}
   124  	slot := interfaces.NewConnectedSlot(&snap.SlotInfo{
   125  		Snap: &snap.Info{
   126  			SuggestedName: "location",
   127  			Apps:          map[string]*snap.AppInfo{"app": app},
   128  		},
   129  		Name:      "location",
   130  		Interface: "location",
   131  		Apps:      map[string]*snap.AppInfo{"app": app},
   132  	}, nil, nil)
   133  
   134  	apparmorSpec := &apparmor.Specification{}
   135  	err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, slot)
   136  	c.Assert(err, IsNil)
   137  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.location-consumer.app"})
   138  	c.Assert(apparmorSpec.SnippetForTag("snap.location-consumer.app"), testutil.Contains, `peer=(label="snap.location.app"),`)
   139  }
   140  
   141  // The label glob when all apps are bound to the location plug
   142  func (s *LocationControlInterfaceSuite) TestConnectedSlotSnippetUsesPlugLabelAll(c *C) {
   143  	app1 := &snap.AppInfo{Name: "app1"}
   144  	app2 := &snap.AppInfo{Name: "app2"}
   145  	plug := interfaces.NewConnectedPlug(&snap.PlugInfo{
   146  		Snap: &snap.Info{
   147  			SuggestedName: "location",
   148  			Apps:          map[string]*snap.AppInfo{"app1": app1, "app2": app2},
   149  		},
   150  		Name:      "location",
   151  		Interface: "location",
   152  		Apps:      map[string]*snap.AppInfo{"app1": app1, "app2": app2},
   153  	}, nil, nil)
   154  
   155  	apparmorSpec := &apparmor.Specification{}
   156  	err := apparmorSpec.AddConnectedSlot(s.iface, plug, s.slot)
   157  	c.Assert(err, IsNil)
   158  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.location.app2"})
   159  	c.Assert(apparmorSpec.SnippetForTag("snap.location.app2"), testutil.Contains, `peer=(label="snap.location.*"),`)
   160  }
   161  
   162  // The label uses alternation when some, but not all, apps is bound to the location plug
   163  func (s *LocationControlInterfaceSuite) TestConnectedSlotSnippetUsesPlugLabelSome(c *C) {
   164  	app1 := &snap.AppInfo{Name: "app1"}
   165  	app2 := &snap.AppInfo{Name: "app2"}
   166  	app3 := &snap.AppInfo{Name: "app3"}
   167  	plug := interfaces.NewConnectedPlug(&snap.PlugInfo{
   168  		Snap: &snap.Info{
   169  			SuggestedName: "location",
   170  			Apps:          map[string]*snap.AppInfo{"app1": app1, "app2": app2, "app3": app3},
   171  		},
   172  		Name:      "location",
   173  		Interface: "location",
   174  		Apps:      map[string]*snap.AppInfo{"app1": app1, "app2": app2},
   175  	}, nil, nil)
   176  
   177  	apparmorSpec := &apparmor.Specification{}
   178  	err := apparmorSpec.AddConnectedSlot(s.iface, plug, s.slot)
   179  	c.Assert(err, IsNil)
   180  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.location.app2"})
   181  	c.Assert(apparmorSpec.SnippetForTag("snap.location.app2"), testutil.Contains, `peer=(label="snap.location.{app1,app2}"),`)
   182  }
   183  
   184  // The label uses short form when exactly one app is bound to the location plug
   185  func (s *LocationControlInterfaceSuite) TestConnectedSlotSnippetUsesPlugLabelOne(c *C) {
   186  	app := &snap.AppInfo{Name: "app"}
   187  	plug := interfaces.NewConnectedPlug(&snap.PlugInfo{
   188  		Snap: &snap.Info{
   189  			SuggestedName: "location",
   190  			Apps:          map[string]*snap.AppInfo{"app": app},
   191  		},
   192  		Name:      "location",
   193  		Interface: "location",
   194  		Apps:      map[string]*snap.AppInfo{"app": app},
   195  	}, nil, nil)
   196  
   197  	apparmorSpec := &apparmor.Specification{}
   198  	err := apparmorSpec.AddConnectedSlot(s.iface, plug, s.slot)
   199  	c.Assert(err, IsNil)
   200  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.location.app2"})
   201  	c.Assert(apparmorSpec.SnippetForTag("snap.location.app2"), testutil.Contains, `peer=(label="snap.location.app"),`)
   202  }
   203  
   204  func (s *LocationControlInterfaceSuite) TestInterfaces(c *C) {
   205  	c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface)
   206  }