blob: 317a6eb11db420de980d9fcedb8f13a0a10c1951 [file] [log] [blame]
David Pursellbdf81e72014-11-03 17:28:09 -08001// 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
43namespace debugd {
44
45// Templated wrapper to enforce tool access restrictions. See comments at the
46// top of the file for usage notes.
47template <class T>
48class 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
Xiaohui Chena8bced82015-02-27 10:35:26 -080091 const DevModeNoOwnerRestriction& restriction() const {
92 return restriction_;
93 }
94
David Pursellbdf81e72014-11-03 17:28:09 -080095 private:
96 T tool_;
97 DevModeNoOwnerRestriction restriction_;
98
99 DISALLOW_COPY_AND_ASSIGN(RestrictedToolWrapper);
100};
101
102} // namespace debugd
103
104#endif // DEBUGD_SRC_RESTRICTED_TOOL_WRAPPER_H_