David Pursell | bdf81e7 | 2014-11-03 17:28:09 -0800 | [diff] [blame] | 1 | // Copyright 2014 The Chromium OS 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 | // This file provides the RestrictedToolWrapper template class, which helps |
| 6 | // control access to tools that should not always be available for use. Typical |
| 7 | // usage will look something like this: |
| 8 | // |
| 9 | // // Instantiate the tool wrapper. |
| 10 | // RestrictedToolWrapper<FooTool>* foo_tool_wrapper = |
| 11 | // new RestrictedToolWrapper<FooTool>(...); |
| 12 | // |
| 13 | // // Unwrap and use the tool. |
| 14 | // DBus::Error error; |
| 15 | // int result = 0; |
| 16 | // foo_tool_wrapper_->CallToolFunction([&result, &error] (FooTool* tool) { |
| 17 | // result = tool->ToolFunction(&error); |
| 18 | // }, |
| 19 | // &error); |
| 20 | // |
| 21 | // Some advantages of using a wrapper rather than putting the condition check |
| 22 | // inside the tool functions themselves are: |
| 23 | // 1. Conditions are declared in a single location during tool instantiation, |
| 24 | // rather than being spread around into each tool implementation. |
| 25 | // 2. The compiler prevents forgotten condition checks, since trying to use a |
| 26 | // wrapper directly will cause compilation errors. This becomes important |
| 27 | // with multiple access-restricted functions to avoid having to manually |
| 28 | // put the right condition in each one. |
| 29 | // 3. Reusability - currently only the DevFeaturesTool class is wrapped, |
| 30 | // but the template wrapper could be applied to future classes without |
| 31 | // any condition logic in the classes themselves. |
| 32 | |
| 33 | #ifndef DEBUGD_SRC_RESTRICTED_TOOL_WRAPPER_H_ |
| 34 | #define DEBUGD_SRC_RESTRICTED_TOOL_WRAPPER_H_ |
| 35 | |
| 36 | #include <string> |
| 37 | |
| 38 | #include <base/macros.h> |
| 39 | #include <dbus-c++/dbus.h> |
| 40 | |
| 41 | #include "debugd/src/dev_mode_no_owner_restriction.h" |
| 42 | |
| 43 | namespace debugd { |
| 44 | |
| 45 | // Templated wrapper to enforce tool access restrictions. See comments at the |
| 46 | // top of the file for usage notes. |
| 47 | template <class T> |
| 48 | class RestrictedToolWrapper { |
| 49 | public: |
| 50 | // Tools without a default constructor may need specialized |
| 51 | // RestrictedToolWrapper classes for additional constructor parameters. If |
| 52 | // possible, use a tool Initialize() function instead of passing additional |
| 53 | // parameters to the constructor. |
| 54 | explicit RestrictedToolWrapper(DBus::Connection* system_dbus) |
| 55 | : restriction_(system_dbus) {} |
| 56 | |
| 57 | ~RestrictedToolWrapper() = default; |
| 58 | |
| 59 | // Returns a raw pointer to the underlying tool instance if both conditions |
| 60 | // from the DevModeNoOwnerRestriction class are met: |
| 61 | // 1. Device is in dev mode. |
| 62 | // 2. Device has no owner. |
| 63 | // Otherwise, returns nullptr and |error| is set (if it's non-null). |
| 64 | // |
| 65 | // Do not store the direct tool pointer longer than needed for immediate use, |
| 66 | // to avoid bypassing the wrapper's condition checks. Prefer to use |
| 67 | // CallToolFunction() when possible to consolidate common access logic. |
| 68 | T* GetTool(DBus::Error* error) { |
| 69 | if (restriction_.AllowToolUse(error)) { |
| 70 | return &tool_; |
| 71 | } |
| 72 | return nullptr; |
| 73 | } |
| 74 | |
| 75 | // Attempts to unwrap the underlying tool and call a function. Typically |
| 76 | // |function| will be a lambda to perform whatever task is needed; the only |
| 77 | // restriction is that the function must only take a T* as its argument. |
| 78 | // |function| will not be called if tool access fails. |
| 79 | // |
| 80 | // If access fails, returns false and |error| is set (if it's non-null). |
| 81 | template <class Func> |
| 82 | bool CallToolFunction(Func function, DBus::Error* error) { |
| 83 | T* tool = GetTool(error); |
| 84 | if (tool) { |
| 85 | function(tool); |
| 86 | return true; |
| 87 | } |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | private: |
| 92 | T tool_; |
| 93 | DevModeNoOwnerRestriction restriction_; |
| 94 | |
| 95 | DISALLOW_COPY_AND_ASSIGN(RestrictedToolWrapper); |
| 96 | }; |
| 97 | |
| 98 | } // namespace debugd |
| 99 | |
| 100 | #endif // DEBUGD_SRC_RESTRICTED_TOOL_WRAPPER_H_ |