github.com/anonymouse64/snapd@v0.0.0-20210824153203-04c4c42d842d/usersession/userd/privileged_desktop_launcher_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2021 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 userd_test
    21  
    22  import (
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  	"strings"
    27  
    28  	. "gopkg.in/check.v1"
    29  
    30  	"github.com/snapcore/snapd/dirs"
    31  	"github.com/snapcore/snapd/systemd"
    32  	"github.com/snapcore/snapd/testutil"
    33  	"github.com/snapcore/snapd/usersession/userd"
    34  )
    35  
    36  type privilegedDesktopLauncherSuite struct {
    37  	testutil.BaseTest
    38  
    39  	launcher *userd.PrivilegedDesktopLauncher
    40  }
    41  
    42  var _ = Suite(&privilegedDesktopLauncherSuite{})
    43  
    44  func (s *privilegedDesktopLauncherSuite) SetUpTest(c *C) {
    45  	s.BaseTest.SetUpTest(c)
    46  
    47  	dirs.SetRootDir(c.MkDir())
    48  	s.launcher = &userd.PrivilegedDesktopLauncher{}
    49  
    50  	c.Assert(os.MkdirAll(dirs.SnapDesktopFilesDir, 0755), IsNil)
    51  	c.Assert(os.MkdirAll(filepath.Join(dirs.GlobalRootDir, "/usr/share/applications"), 0755), IsNil)
    52  
    53  	var rawMircadeDesktop = `[Desktop Entry]
    54    X-SnapInstanceName=mircade
    55    Name=mircade
    56    Exec=env BAMF_DESKTOP_FILE_HINT=/var/lib/snapd/desktop/applications/mircade_mircade.desktop /snap/bin/mircade
    57    Icon=/snap/mircade/143/meta/gui/mircade.png
    58    Comment=Sample confined desktop
    59    Type=Application
    60    Categories=Game
    61    `
    62  	tmpMircadeDesktop := strings.Replace(rawMircadeDesktop, "/var/lib/snapd/desktop/applications", dirs.SnapDesktopFilesDir, -1)
    63  	desktopContent := strings.Replace(tmpMircadeDesktop, "/snap/bin/", dirs.SnapBinariesDir, -1)
    64  
    65  	deskTopFile := filepath.Join(dirs.SnapDesktopFilesDir, "mircade_mircade.desktop")
    66  	c.Assert(ioutil.WriteFile(deskTopFile, []byte(desktopContent), 0644), IsNil)
    67  
    68  	// Create a shadowed desktop file ID
    69  	c.Assert(ioutil.WriteFile(filepath.Join(dirs.GlobalRootDir, "/usr/share/applications/shadow-test.desktop"), []byte("[Desktop Entry]"), 0644), IsNil)
    70  	c.Assert(ioutil.WriteFile(filepath.Join(dirs.SnapDesktopFilesDir, "shadow-test.desktop"), []byte("[Desktop Entry]"), 0644), IsNil)
    71  
    72  	s.mockEnv("HOME", filepath.Join(dirs.GlobalRootDir, "/home/user"))
    73  	s.mockEnv("XDG_DATA_HOME", "")
    74  	s.mockEnv("XDG_DATA_DIRS", strings.Join([]string{
    75  		filepath.Join(dirs.GlobalRootDir, "/usr/share"),
    76  		filepath.Dir(dirs.SnapDesktopFilesDir),
    77  	}, ":"))
    78  
    79  	restore := systemd.MockSystemctl(func(cmd ...string) ([]byte, error) {
    80  		return []byte("systemd 246\n+PAM and more"), nil
    81  	})
    82  	s.AddCleanup(restore)
    83  }
    84  
    85  func (s *privilegedDesktopLauncherSuite) TearDownTest(c *C) {
    86  	s.BaseTest.TearDownTest(c)
    87  }
    88  
    89  func (s *privilegedDesktopLauncherSuite) mockEnv(key, value string) {
    90  	old := os.Getenv(key)
    91  	os.Setenv(key, value)
    92  	s.AddCleanup(func() {
    93  		os.Setenv(key, old)
    94  	})
    95  }
    96  
    97  func (s *privilegedDesktopLauncherSuite) TestDesktopFileLookup(c *C) {
    98  	// We have more extensive tests for this API in
    99  	// privileged_desktop_launcher_internal_test.go: here we just
   100  	// test it without mocking the stat calls.
   101  	filename, err := userd.DesktopFileIDToFilename("mircade_mircade.desktop")
   102  	c.Assert(err, IsNil)
   103  	err = userd.VerifyDesktopFileLocation(filename)
   104  	c.Check(err, IsNil)
   105  }
   106  
   107  func (s *privilegedDesktopLauncherSuite) TestOpenDesktopEntrySucceedsWithGoodDesktopId(c *C) {
   108  	cmd := testutil.MockCommand(c, "systemd-run", "true")
   109  	defer cmd.Restore()
   110  
   111  	err := s.launcher.OpenDesktopEntry("mircade_mircade.desktop", ":some-dbus-sender")
   112  	c.Check(err, IsNil)
   113  }
   114  
   115  func (s *privilegedDesktopLauncherSuite) TestOpenDesktopEntryFailsWithBadDesktopId(c *C) {
   116  	cmd := testutil.MockCommand(c, "systemd-run", "false")
   117  	defer cmd.Restore()
   118  
   119  	err := s.launcher.OpenDesktopEntry("not-mircade_mircade.desktop", ":some-dbus-sender")
   120  	c.Assert(err, ErrorMatches, `cannot find desktop file for "not-mircade_mircade.desktop"`)
   121  }
   122  
   123  func (s *privilegedDesktopLauncherSuite) TestOpenDesktopEntryFailsWithBadExecutable(c *C) {
   124  	cmd := testutil.MockCommand(c, "systemd-run", "false")
   125  	defer cmd.Restore()
   126  
   127  	err := s.launcher.OpenDesktopEntry("mircade_mircade.desktop", ":some-dbus-sender")
   128  	c.Check(err, ErrorMatches, `cannot run ".*": exit status 1`)
   129  }
   130  
   131  func (s *privilegedDesktopLauncherSuite) TestOpenDesktopEntryFailsForNonSnap(c *C) {
   132  	cmd := testutil.MockCommand(c, "systemd-run", "false")
   133  	defer cmd.Restore()
   134  
   135  	err := s.launcher.OpenDesktopEntry("shadow-test.desktop", ":some-dbus-sender")
   136  	c.Check(err, ErrorMatches, `only launching snap applications from .* is supported`)
   137  }