1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/media/chromeos_login_media_access_handler.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "base/values.h"
11 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
12 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
13 #include "chrome/browser/chromeos/settings/cros_settings.h"
14 #include "chrome/common/url_constants.h"
15 #include "chromeos/settings/cros_settings_names.h"
16 #include "components/content_settings/core/common/content_settings_pattern.h"
17 #include "content/public/browser/render_frame_host.h"
18 #include "url/gurl.h"
19
ChromeOSLoginMediaAccessHandler()20 ChromeOSLoginMediaAccessHandler::ChromeOSLoginMediaAccessHandler() {}
21
~ChromeOSLoginMediaAccessHandler()22 ChromeOSLoginMediaAccessHandler::~ChromeOSLoginMediaAccessHandler() {}
23
SupportsStreamType(content::WebContents * web_contents,const blink::mojom::MediaStreamType type,const extensions::Extension * extension)24 bool ChromeOSLoginMediaAccessHandler::SupportsStreamType(
25 content::WebContents* web_contents,
26 const blink::mojom::MediaStreamType type,
27 const extensions::Extension* extension) {
28 if (!web_contents)
29 return false;
30 chromeos::LoginDisplayHost* host = chromeos::LoginDisplayHost::default_host();
31 return host && web_contents == host->GetOobeWebContents();
32 }
33
CheckMediaAccessPermission(content::RenderFrameHost * render_frame_host,const GURL & security_origin,blink::mojom::MediaStreamType type,const extensions::Extension * extension)34 bool ChromeOSLoginMediaAccessHandler::CheckMediaAccessPermission(
35 content::RenderFrameHost* render_frame_host,
36 const GURL& security_origin,
37 blink::mojom::MediaStreamType type,
38 const extensions::Extension* extension) {
39 if (type != blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE)
40 return false;
41
42 // When creating new user (including supervised user), we must be able to use
43 // the camera to capture a user image.
44 if (security_origin.spec() == chrome::kChromeUIOobeURL)
45 return true;
46
47 const chromeos::CrosSettings* const settings = chromeos::CrosSettings::Get();
48 if (!settings)
49 return false;
50
51 // The following checks are for SAML logins.
52 const base::Value* const raw_list_value =
53 settings->GetPref(chromeos::kLoginVideoCaptureAllowedUrls);
54 if (!raw_list_value)
55 return false;
56
57 const base::ListValue* list_value;
58 const bool is_list = raw_list_value->GetAsList(&list_value);
59 DCHECK(is_list);
60 for (const auto& base_value : *list_value) {
61 std::string value;
62 if (base_value.GetAsString(&value)) {
63 const ContentSettingsPattern pattern =
64 ContentSettingsPattern::FromString(value);
65 // Force administrators to specify more-specific patterns by ignoring the
66 // global wildcard pattern.
67 if (pattern == ContentSettingsPattern::Wildcard()) {
68 VLOG(1) << "Ignoring wildcard URL pattern: " << value;
69 continue;
70 }
71 if (pattern.IsValid() && pattern.Matches(security_origin))
72 return true;
73 }
74 }
75 return false;
76 }
77
HandleRequest(content::WebContents * web_contents,const content::MediaStreamRequest & request,content::MediaResponseCallback callback,const extensions::Extension * extension)78 void ChromeOSLoginMediaAccessHandler::HandleRequest(
79 content::WebContents* web_contents,
80 const content::MediaStreamRequest& request,
81 content::MediaResponseCallback callback,
82 const extensions::Extension* extension) {
83 bool audio_allowed = false;
84 bool video_allowed =
85 request.video_type ==
86 blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE &&
87 CheckMediaAccessPermission(
88 content::RenderFrameHost::FromID(request.render_process_id,
89 request.render_frame_id),
90 request.security_origin,
91 blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE, extension);
92
93 CheckDevicesAndRunCallback(web_contents, request, std::move(callback),
94 audio_allowed, video_allowed);
95 }
96