blob: 8e98b9c8288493a061a4d7281fa0f8728e8dd169 [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
David Pursellbdf81e72014-11-03 17:28:09 -080036#include <base/macros.h>
37#include <dbus-c++/dbus.h>
38
39#include "debugd/src/dev_mode_no_owner_restriction.h"
40
41namespace debugd {
42
43// Templated wrapper to enforce tool access restrictions. See comments at the
44// top of the file for usage notes.
45template <class T>
46class RestrictedToolWrapper {
47 public:
48 // Tools without a default constructor may need specialized
49 // RestrictedToolWrapper classes for additional constructor parameters. If
50 // possible, use a tool Initialize() function instead of passing additional
51 // parameters to the constructor.
52 explicit RestrictedToolWrapper(DBus::Connection* system_dbus)
53 : restriction_(system_dbus) {}
54
55 ~RestrictedToolWrapper() = default;
56
57 // Returns a raw pointer to the underlying tool instance if both conditions
58 // from the DevModeNoOwnerRestriction class are met:
59 // 1. Device is in dev mode.
60 // 2. Device has no owner.
61 // Otherwise, returns nullptr and |error| is set (if it's non-null).
62 //
63 // Do not store the direct tool pointer longer than needed for immediate use,
64 // to avoid bypassing the wrapper's condition checks. Prefer to use
65 // CallToolFunction() when possible to consolidate common access logic.
66 T* GetTool(DBus::Error* error) {
67 if (restriction_.AllowToolUse(error)) {
68 return &tool_;
69 }
70 return nullptr;
71 }
72
73 // Attempts to unwrap the underlying tool and call a function. Typically
74 // |function| will be a lambda to perform whatever task is needed; the only
75 // restriction is that the function must only take a T* as its argument.
76 // |function| will not be called if tool access fails.
77 //
78 // If access fails, returns false and |error| is set (if it's non-null).
79 template <class Func>
80 bool CallToolFunction(Func function, DBus::Error* error) {
81 T* tool = GetTool(error);
82 if (tool) {
83 function(tool);
84 return true;
85 }
86 return false;
87 }
88
Xiaohui Chena8bced82015-02-27 10:35:26 -080089 const DevModeNoOwnerRestriction& restriction() const {
90 return restriction_;
91 }
92
David Pursellbdf81e72014-11-03 17:28:09 -080093 private:
94 T tool_;
95 DevModeNoOwnerRestriction restriction_;
96
97 DISALLOW_COPY_AND_ASSIGN(RestrictedToolWrapper);
98};
99
100} // namespace debugd
101
102#endif // DEBUGD_SRC_RESTRICTED_TOOL_WRAPPER_H_