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 }