privetd: Compare user scope with minimalRole for local commands

Prived passes current auth scope corresponding to the current
/privet/v3/commands/execute requests to buffet.
Buffet compare scope with minimalRole of requested command and denies
request if scope is not enough.

BUG=brillo:808
TEST=`FEATURES=test emerge-gizmo buffet privetd`

Change-Id: Ib691184460fcd9d099e0688eaeadf831229672aa
Reviewed-on: https://chromium-review.googlesource.com/274234
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/buffet_client.cc b/buffet/buffet_client.cc
index 8408a46..ab8f189 100644
--- a/buffet/buffet_client.cc
+++ b/buffet/buffet_client.cc
@@ -365,7 +365,7 @@
   void CallAddCommand(const std::string& command, ManagerProxy* manager_proxy) {
     ErrorPtr error;
     std::string id;
-    if (!manager_proxy->AddCommand(command, &id, &error)) {
+    if (!manager_proxy->AddCommand(command, "owner", &id, &error)) {
       return ReportError(error.get());
     }
     OnJobComplete();
diff --git a/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml b/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml
index 9a3b9c2..0fa4282 100644
--- a/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml
+++ b/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml
@@ -45,6 +45,7 @@
     </method>
     <method name="AddCommand">
       <arg name="json_command" type="s" direction="in"/>
+      <arg name="user_role" type="s" direction="in"/>
       <arg name="id" type="s" direction="out"/>
       <annotation name="org.chromium.DBus.Method.Kind" value="async"/>
     </method>
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 23e4fca..40ef9c0 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -162,7 +162,8 @@
 }
 
 void Manager::AddCommand(DBusMethodResponse<std::string> response,
-                         const std::string& json_command) {
+                         const std::string& json_command,
+                         const std::string& in_user_role) {
   static int next_id = 0;
   std::string error_message;
   std::unique_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
@@ -181,6 +182,24 @@
     response->ReplyWithError(error.get());
     return;
   }
+
+  UserRole role;
+  if (!FromString(in_user_role, &role, &error)) {
+    response->ReplyWithError(error.get());
+    return;
+  }
+
+  UserRole minimal_role =
+      command_instance->GetCommandDefinition()->GetMinimalRole();
+  if (role < minimal_role) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, kErrorDomainGCD, "access_denied",
+        "User role '%s' less than minimal: '%s'", ToString(role).c_str(),
+        ToString(minimal_role).c_str());
+    response->ReplyWithError(error.get());
+    return;
+  }
+
   std::string id = std::to_string(++next_id);
   command_instance->SetID(id);
   command_manager_->AddCommand(std::move(command_instance));
diff --git a/buffet/manager.h b/buffet/manager.h
index 2acb73e..35e6e25 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -77,7 +77,8 @@
                    const chromeos::VariantDictionary& property_set) override;
   bool GetState(chromeos::ErrorPtr* error, std::string* state) override;
   void AddCommand(DBusMethodResponse<std::string> response,
-                  const std::string& json_command) override;
+                  const std::string& json_command,
+                  const std::string& in_user_role) override;
   void GetCommand(DBusMethodResponse<std::string> response,
                   const std::string& id) override;
   void SetCommandVisibility(