Commit 722b7f23 authored by Shane Caraveo's avatar Shane Caraveo
Browse files

Bug 1742471 enforce addon gating of webmidi interfaces r=gsvelto

parent 34d4b638
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -3808,6 +3808,24 @@ bool nsContentUtils::IsExactSitePermDeny(nsIPrincipal* aPrincipal,
                      true);
}

bool nsContentUtils::HasExactSitePerm(nsIPrincipal* aPrincipal,
                                      const nsACString& aType) {
  if (!aPrincipal) {
    return false;
  }

  nsCOMPtr<nsIPermissionManager> permMgr =
      components::PermissionManager::Service();
  NS_ENSURE_TRUE(permMgr, false);

  uint32_t perm;
  nsresult rv =
      permMgr->TestExactPermissionFromPrincipal(aPrincipal, aType, &perm);
  NS_ENSURE_SUCCESS(rv, false);

  return perm != nsIPermissionManager::UNKNOWN_ACTION;
}

static const char* gEventNames[] = {"event"};
static const char* gSVGEventNames[] = {"evt"};
// for b/w compat, the first name to onerror is still 'event', even though it
+4 −0
Original line number Diff line number Diff line
@@ -890,6 +890,10 @@ class nsContentUtils {
  static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal,
                                  const nsACString& aType);

  // Returns true if the pref exists and is not UNKNOWN_ACTION.
  static bool HasExactSitePerm(nsIPrincipal* aPrincipal,
                               const nsACString& aType);

  // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
  static bool HaveEqualPrincipals(Document* aDoc1, Document* aDoc2);

+15 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "mozilla/dom/Document.h"
#include "mozilla/dom/MIDIAccessManager.h"
#include "mozilla/dom/MIDIOptionsBinding.h"
#include "mozilla/StaticPrefs_dom.h"
#include "nsIGlobalObject.h"
#include "mozilla/Preferences.h"
#include "nsContentUtils.h"
@@ -89,6 +90,20 @@ MIDIPermissionRequest::Run() {
    return NS_OK;
  }

  // If midi is addon-gated, the we only pass through to ask permission if
  // the permission already exists.  This allows for the user possibly changing
  // the permission to ask, or deny and having the existing UX properly handle
  // the outcome.
  if (
#ifndef RELEASE_OR_BETA
      StaticPrefs::dom_webmidi_gated() &&
#endif
      !nsContentUtils::HasExactSitePerm(mPrincipal, "midi"_ns) &&
      !nsContentUtils::HasExactSitePerm(mPrincipal, "midi-sysex"_ns)) {
    Cancel();
    return NS_OK;
  }

  // If we have no perms, or only have midi and are asking for sysex, pop dialog
  if (NS_FAILED(nsContentPermissionUtils::AskPermission(this, mWindow))) {
    Cancel();
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ scheme = https
[test_midi_permission_prompt.html]
[test_midi_permission_allow.html]
[test_midi_permission_deny.html]
[test_midi_permission_gated.html]
[test_midi_device_enumeration.html]
[test_midi_device_implicit_open_close.html]
[test_midi_device_explicit_open_close.html]
+60 −0
Original line number Diff line number Diff line
<html>
  <head>
    <title>WebMIDI Listener Test</title>
    <script src="/tests/SimpleTest/SimpleTest.js"></script>
    <script type="application/javascript" src="MIDITestUtils.js"></script>
  </head>

  <body onload="runTests()">
    <script class="testbody" type="application/javascript">
    SimpleTest.waitForExplicitFinish();

    async function runTests() {
      await SpecialPowers.pushPrefEnv({
        set: [["dom.webmidi.enabled", true]],
      });
      ok(
        await SpecialPowers.testPermission(
          "midi",
          SpecialPowers.Services.perms.UNKNOWN_ACTION,
          document
        ),
        "midi value should have UNKNOWN permission"
      );
      ok(
        await SpecialPowers.testPermission(
          "midi-sysex",
          SpecialPowers.Services.perms.UNKNOWN_ACTION,
          document
        ),
        "midi-sysex value should have UNKNOWN permission"
      );

      // Gated permission should fail without addon installed.
      try {
        await navigator.requestMIDIAccess({ sysex: false });
        ok(false, "MIDI Access Request gate failed");
      } catch (ex) {
        ok(true, "MIDI Access Request denied by default");
      }

      // When an addon is installed, the permission is inserted.  Test
      // that the request succeeds after we insert the permission.
      await SpecialPowers.addPermission(
        "midi",
        SpecialPowers.Services.perms.ALLOW_ACTION,
        document
      );

      // Gated permission should allow access after addon inserted permission.
      try {
        await navigator.requestMIDIAccess({ sysex: false });
        ok(true, "MIDI Access Request allowed");
      } catch (ex) {
        ok(false, "MIDI Access Request failed");
      }
      SimpleTest.finish();
    }
    </script>
  </body>
</html>
Loading