Skip to content

Commit

Permalink
Add privacy tab for plugin settings
Browse files Browse the repository at this point in the history
Implemented a new privacy tab in the plugin settings view in the Flutter UI. This tab displays access permissions required by a specific plugin. Enhanced the Wox plugin system to support these changes, adding the necessary code configurations. Also updated the browser plugin to leverage these new features.
  • Loading branch information
qianlifeng committed May 23, 2024
1 parent 3ccb693 commit 4a5792e
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 1 deletion.
26 changes: 26 additions & 0 deletions Wox.UI.Flutter/wox/lib/entity/wox_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class PluginDetail {
late bool isDisable;
late List<PluginSettingDefinitionItem> settingDefinitions;
late PluginSetting setting;
late List<MetadataFeature> features;

PluginDetail.empty() {
id = '';
Expand All @@ -40,6 +41,7 @@ class PluginDetail {
isDisable = false;
settingDefinitions = <PluginSettingDefinitionItem>[];
setting = PluginSetting.empty();
features = <MetadataFeature>[];
}

PluginDetail.fromJson(Map<String, dynamic> json) {
Expand Down Expand Up @@ -97,6 +99,15 @@ class PluginDetail {
} else {
setting = PluginSetting.empty();
}

if (json['Features'] != null) {
features = <MetadataFeature>[];
json['Features'].forEach((v) {
features.add(MetadataFeature.fromJson(v));
});
} else {
features = <MetadataFeature>[];
}
}
}

Expand Down Expand Up @@ -165,3 +176,18 @@ class PluginQueryCommand {
description = json['Description'];
}
}

class MetadataFeature {
late String name;
late Map<String, String> params;

MetadataFeature.fromJson(Map<String, dynamic> json) {
name = json['Name'];

if (json['Params'] != null) {
params = json['Params'].cast<String, String>();
} else {
params = <String, String>{};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart' as material;
import 'package:flutter/services.dart';
import 'package:flutter_image_slideshow/flutter_image_slideshow.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:wox/components/plugin/wox_setting_plugin_head_view.dart';
import 'package:wox/components/plugin/wox_setting_plugin_label_view.dart';
import 'package:wox/components/plugin/wox_setting_plugin_newline_view.dart';
import 'package:wox/components/plugin/wox_setting_plugin_select_view.dart';
import 'package:wox/components/plugin/wox_setting_plugin_table_view.dart';
import 'package:wox/components/wox_image_view.dart';
import 'package:wox/components/wox_tooltip_view.dart';
import 'package:wox/entity/setting/wox_plugin_setting_label.dart';
import 'package:wox/entity/setting/wox_plugin_setting_table.dart';
import 'package:wox/entity/wox_plugin.dart';
Expand Down Expand Up @@ -306,6 +308,13 @@ class WoxSettingPluginView extends GetView<WoxSettingController> {
),
content: pluginTabSetting(),
),
dt.TabData(
index: 2,
title: const material.Tab(
child: Text('Privacy'),
),
content: pluginTabPrivacy(),
),
],
onTabControllerUpdated: (tabController) {
controller.activePluginTabController = tabController;
Expand Down Expand Up @@ -435,6 +444,92 @@ class WoxSettingPluginView extends GetView<WoxSettingController> {
});
}

Widget pluginTabPrivacy() {
var plugin = controller.activePluginDetail.value;
var noDataAccess = const Padding(
padding: EdgeInsets.all(16),
child: Text('This plugin requires no data access'),
);

if (plugin.features.isEmpty) {
return noDataAccess;
}

//check if "queryEnv" feature is exist and list it's params
var queryEnv = plugin.features.where((element) => element.name == "queryEnv").toList();
if (queryEnv.isEmpty) {
return noDataAccess;
}

List<String> params = [];
queryEnv.first.params.forEach((key, value) {
if (value == "true") {
params.add(key);
}
});
if (params.isEmpty) {
return noDataAccess;
}

return Padding(
padding: const EdgeInsets.all(16.0),
child: Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This plugin requires access to the following data:'),
const SizedBox(height: 20),
...params.map((e) {
if (e == "requireActiveWindowName") {
return privacyItem(
material.Icons.window,
'Active window name',
'E.g. you are using google chrome to view webpages, you activate Wox and this plugin will get the active window name as "Google Chrome"',
);
}
if (e == "requireActiveBrowserUrl") {
return privacyItem(
material.Icons.web_sharp,
'Active browser URL',
'E.g. you are using google chrome to view webpages, you activate Wox and this plugin will get the url of active tab you are viewing',
);
}
return Text(e);
}),
],
),
),
);
}

Widget privacyItem(IconData icon, String title, String description) {
return Column(
children: [
Row(
children: [
Icon(icon),
SizedBox(width: 10),
Text(title),
],
),
const SizedBox(height: 10),
Row(
children: [
const SizedBox(width: 30),
Flexible(
child: Text(
description,
style: TextStyle(
color: Colors.grey[100],
),
),
),
],
)
],
);
}

@override
Widget build(BuildContext context) {
return Padding(
Expand Down
37 changes: 37 additions & 0 deletions Wox/plugin/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type Manager struct {
ui share.UI
resultCache *util.HashMap[string, *QueryResultCache]
debounceQueryTimer *util.HashMap[string, *debounceTimer]

activeBrowserUrl string //active browser url before wox is activated
}

func GetPluginManager() *Manager {
Expand Down Expand Up @@ -73,6 +75,10 @@ func (m *Manager) Stop(ctx context.Context) {
}
}

func (m *Manager) SetActiveBrowserUrl(url string) {
m.activeBrowserUrl = url
}

func (m *Manager) loadPlugins(ctx context.Context) error {
logger.Info(ctx, "start loading plugins")

Expand Down Expand Up @@ -368,6 +374,25 @@ func (m *Manager) canOperateQuery(ctx context.Context, pluginInstance *Instance,
func (m *Manager) queryForPlugin(ctx context.Context, pluginInstance *Instance, query Query) []QueryResult {
logger.Info(ctx, fmt.Sprintf("<%s> start query: %s", pluginInstance.Metadata.Name, query.RawQuery))
start := util.GetSystemTimestamp()

// set query env base on plugin's feature
currentEnv := query.Env
newEnv := QueryEnv{}
if pluginInstance.Metadata.IsSupportFeature(MetadataFeatureQueryEnv) {
queryEnvParams, err := pluginInstance.Metadata.GetFeatureParamsForQueryEnv()
if err != nil {
logger.Error(ctx, fmt.Sprintf("<%s> invalid query env config: %s", pluginInstance.Metadata.Name, err))
} else {
if queryEnvParams.RequireActiveWindowName {
newEnv.ActiveWindowTitle = currentEnv.ActiveWindowTitle
}
if queryEnvParams.RequireActiveBrowserUrl {
newEnv.ActiveBrowserUrl = currentEnv.ActiveBrowserUrl
}
}
}
query.Env = newEnv

results := pluginInstance.Plugin.Query(ctx, query)
logger.Debug(ctx, fmt.Sprintf("<%s> finish query, result count: %d, cost: %dms", pluginInstance.Metadata.Name, len(results), util.GetSystemTimestamp()-start))

Expand Down Expand Up @@ -695,6 +720,7 @@ func (m *Manager) NewQuery(ctx context.Context, plainQuery share.PlainQuery) (Qu
}
query, instance := newQueryInputWithPlugins(newQuery, GetPluginManager().GetPluginInstances())
query.Env.ActiveWindowTitle = m.GetUI().GetActiveWindowName()
query.Env.ActiveBrowserUrl = m.getActiveBrowserUrl(ctx)
return query, instance, nil
}

Expand All @@ -706,12 +732,23 @@ func (m *Manager) NewQuery(ctx context.Context, plainQuery share.PlainQuery) (Qu
Selection: plainQuery.QuerySelection,
}
query.Env.ActiveWindowTitle = window.GetActiveWindowName()
query.Env.ActiveBrowserUrl = m.getActiveBrowserUrl(ctx)
return query, nil, nil
}

return Query{}, nil, errors.New("invalid query type")
}

func (m *Manager) getActiveBrowserUrl(ctx context.Context) string {
activeWindowName := m.GetUI().GetActiveWindowName()
isGoogleChrome := strings.ToLower(activeWindowName) == "google chrome"
if !isGoogleChrome {
return ""
}

return m.activeBrowserUrl
}

func (m *Manager) expandQueryShortcut(ctx context.Context, query string, queryShorts []setting.QueryShortcut) (newQuery string) {
newQuery = query

Expand Down
35 changes: 35 additions & 0 deletions Wox/plugin/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const (
// enable this feature to let Wox don't auto score results
// by default, Wox will auto score results by the frequency of their actioned times
MetadataFeatureIgnoreAutoScore MetadataFeatureName = "ignoreAutoScore"

// enable this feature to get query env in plugin
MetadataFeatureQueryEnv MetadataFeatureName = "queryEnv"
)

// Metadata parsed from plugin.json, see `Plugin.json.md` for more detail
Expand Down Expand Up @@ -83,6 +86,33 @@ func (m *Metadata) GetFeatureParamsForDebounce() (MetadataFeatureParamsDebounce,
return MetadataFeatureParamsDebounce{}, errors.New("plugin does not support debounce feature")
}

func (m *Metadata) GetFeatureParamsForQueryEnv() (MetadataFeatureParamsQueryEnv, error) {
for _, feature := range m.Features {
if strings.ToLower(feature.Name) == strings.ToLower(MetadataFeatureQueryEnv) {
params := MetadataFeatureParamsQueryEnv{
RequireActiveWindowName: false,
RequireActiveBrowserUrl: false,
}

if v, ok := feature.Params["requireActiveWindowName"]; ok {
if v == "true" {
params.RequireActiveWindowName = true
}
}

if v, ok := feature.Params["requireActiveBrowserUrl"]; ok {
if v == "true" {
params.RequireActiveBrowserUrl = true
}
}

return params, nil
}
}

return MetadataFeatureParamsQueryEnv{}, errors.New("plugin does not support queryEnv feature")
}

type MetadataFeature struct {
Name MetadataFeatureName
Params map[string]string
Expand All @@ -105,3 +135,8 @@ type MetadataWithDirectory struct {
type MetadataFeatureParamsDebounce struct {
intervalMs int
}

type MetadataFeatureParamsQueryEnv struct {
RequireActiveWindowName bool
RequireActiveBrowserUrl bool
}
4 changes: 4 additions & 0 deletions Wox/plugin/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func (q *Query) String() string {

type QueryEnv struct {
ActiveWindowTitle string // active window title when user query

// active browser url when user query
// Only available when active window is browser and https://github.com/Wox-launcher/Wox.Chrome.Extension is installed
ActiveBrowserUrl string
}

// Query result return from plugin
Expand Down
10 changes: 9 additions & 1 deletion Wox/plugin/system/browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ func (c *BrowserPlugin) GetMetadata() plugin.Metadata {
"Macos",
"Linux",
},
Features: []plugin.MetadataFeature{
{
Name: "queryEnv",
Params: map[string]string{
"requireActiveWindowName": "true",
},
},
},
SettingDefinitions: []definition.PluginSettingDefinitionItem{
{
Type: definition.PluginSettingDefinitionTypeTextBox,
Expand Down Expand Up @@ -251,7 +259,7 @@ func (c *BrowserPlugin) onUpdateTabs(ctx context.Context, data string) {
})
if exist {
c.activeTab = activeTab
//c.api.Log(ctx, plugin.LogLevelDebug, fmt.Sprintf("active tab: %s", activeTab.Title))
plugin.GetPluginManager().SetActiveBrowserUrl(activeTab.Url)
}

// filter invalid tabs
Expand Down
1 change: 1 addition & 0 deletions Wox/ui/dto/plugin_dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type PluginDto struct {
SupportedOS []string
SettingDefinitions definition.PluginSettingDefinitions // only available when plugin is installed
Setting setting.PluginSetting // only available when plugin is installed
Features []plugin.MetadataFeature // only available when plugin is installed
IsSystem bool
IsDev bool
IsInstalled bool
Expand Down
1 change: 1 addition & 0 deletions Wox/ui/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func convertPluginDto(ctx context.Context, pluginDto dto.PluginDto, pluginInstan
pluginDto.Setting = *pluginInstance.Setting
//only return user pre-defined settings
pluginDto.Setting.Settings = definitionSettings
pluginDto.Features = pluginInstance.Metadata.Features
}

return pluginDto
Expand Down

0 comments on commit 4a5792e

Please sign in to comment.