Skip to content

Commit

Permalink
feat/config_for_root_people (#19)
Browse files Browse the repository at this point in the history
* feat/config_for_root_people

```
  // system administrators can define different constraints in how configurations are loaded
  // this is a mechanism to require root to change these config options
  "system": {
    // do not allow users to tamper with settings at all
    "disable_user_config": false,
    // do not allow remote backend to tamper with settings at all
    "disable_remote_config": false,
    // protected keys are individual settings that can not be changed at remote/user level
    // nested dictionary keys can be defined with "key1:key2" syntax,
    // eg. {"a": {"b": True, "c": False}}
    // to protect "c" you would enter "a:c" in the section below
    "protected_keys": {
        // NOTE: selene backend expects "opt_in" to be changeable in their web ui
        // that effectively gives them a means to enable spying without your input
        // Mycroft AI can be trusted, but you dont need to anymore!
        // The other keys are not currently populated by the remote backend
        // they are defined for protection against bugs and for future proofing
        // (what if facebook buys mycroft tomorrow?)
        "remote": [
            "enclosure",
            "server",
            "system",
            "websocket",
            "gui_websocket",
            "network_tests",
            "listener:wake_word_upload:disable",
            "skills:msm:disabled",
            "skills:upload_skill_manifest",
            "skills:auto_update",
            "skills:priority_skills",
            "skills:blacklisted_skills",
            "opt_in"
        ],
        "user": []
    }
  }
```

authored-by: jarbasai <jarbasai@mailfence.com>
  • Loading branch information
JarbasAl authored Nov 8, 2021
1 parent b2f27d4 commit 7532980
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 63 deletions.
70 changes: 50 additions & 20 deletions mycroft/configuration/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from mycroft.configuration.ovos import is_using_xdg
from mycroft.util.json_helper import load_commented_json, merge_dict
from mycroft.util.log import LOG
from ovos_utils.json_helper import flattened_delete


def is_remote_list(values):
Expand Down Expand Up @@ -198,6 +199,15 @@ def _log_old_location_deprecation(old_user_config=OLD_USER_CONFIG):
BASE_FOLDER))


def _get_system_constraints():
# constraints must come from SYSTEM config
# if not defined then load the DEFAULT constraints
# these settings can not be set anywhere else!
return LocalConf(SYSTEM_CONFIG).get("system") or \
LocalConf(DEFAULT_CONFIG).get("system") or \
{}


class Configuration:
"""Namespace for operations on the configuration singleton."""
__config = {} # Cached config
Expand Down Expand Up @@ -235,28 +245,36 @@ def load_config_stack(configs=None, cache=False, remote=True):
Returns:
(dict) merged dict of all configuration files
"""

# system administrators can define different constraints in how
# configurations are loaded
system_conf = _get_system_constraints()
protected_keys = system_conf.get("protected_keys") or {}
protected_remote = protected_keys.get("remote") or []
protected_user = protected_keys.get("user") or []
skip_user = system_conf.get("disable_user_config", False)
skip_remote = system_conf.get("disable_remote_config", False)

# This includes both the user config and
# /etc/xdg/mycroft/mycroft.conf
xdg_locations = get_xdg_config_locations()

if not configs:
configs = [LocalConf(DEFAULT_CONFIG),
LocalConf(SYSTEM_CONFIG)]
if remote:
configs.append(RemoteConf())

if is_using_xdg():
# deprecation warning
if isfile(OLD_USER_CONFIG):
_log_old_location_deprecation(OLD_USER_CONFIG)
if not skip_remote and remote:
configs.append(RemoteConf())
if not skip_user:
if is_using_xdg():
# deprecation warning
if isfile(OLD_USER_CONFIG):
_log_old_location_deprecation(OLD_USER_CONFIG)
configs.append(LocalConf(OLD_USER_CONFIG))
configs += [LocalConf(p) for p in xdg_locations]
else:
# just load the pre defined old locations
configs.append(LocalConf(OLD_USER_CONFIG))

# This includes both the user config and
# /etc/xdg/mycroft/mycroft.conf
configs += [LocalConf(p) for p in get_xdg_config_locations()]

configs.append(Configuration.__patch)
else:
# just load the pre defined locations
configs += [LocalConf(OLD_USER_CONFIG),
Configuration.__patch]

configs.append(Configuration.__patch)
else:
# Handle strings in stack
for index, item in enumerate(configs):
Expand All @@ -265,8 +283,20 @@ def load_config_stack(configs=None, cache=False, remote=True):

# Merge all configs into one
base = {}
for c in configs:
merge_dict(base, c)
for cfg in configs:
# check for protected keys in remote config (changes blocked by system)
if isinstance(cfg, RemoteConf):
if skip_remote: # remote config disabled at system level
continue
# delete protected keys from remote config
flattened_delete(cfg, protected_remote)
# check for protected keys in user config (changes blocked by system)
elif isinstance(cfg, LocalConf) and cfg.path in xdg_locations + [OLD_USER_CONFIG]:
if skip_user: # user config disabled at system level
continue
# delete protected keys from user config
flattened_delete(cfg, protected_user)
merge_dict(base, cfg)

# copy into cache
if cache:
Expand Down
90 changes: 47 additions & 43 deletions mycroft/configuration/mycroft.conf
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,43 @@

},

// system administrators can define different constraints in how configurations are loaded
// this is a mechanism to require root to change these config options
"system": {
// do not allow users to tamper with settings at all
"disable_user_config": false,
// do not allow remote backend to tamper with settings at all
"disable_remote_config": false,
// protected keys are individual settings that can not be changed at remote/user level
// nested dictionary keys can be defined with "key1:key2" syntax,
// eg. {"a": {"b": True, "c": False}}
// to protect "c" you would enter "a:c" in the section below
"protected_keys": {
// NOTE: selene backend expects "opt_in" to be changeable in their web ui
// that effectively gives them a means to enable spying without your input
// Mycroft AI can be trusted, but you dont need to anymore!
// The other keys are not currently populated by the remote backend
// they are defined for protection against bugs and for future proofing
// (what if facebook buys mycroft tomorrow?)
"remote": [
"enclosure",
"server",
"system",
"websocket",
"gui_websocket",
"network_tests",
"listener:wake_word_upload:disable",
"skills:msm:disabled",
"skills:upload_skill_manifest",
"skills:auto_update",
"skills:priority_skills",
"skills:blacklisted_skills",
"opt_in"
],
"user": []
}
},

// Address of the REMOTE server
"server": {
"url": "https://api.mycroft.ai",
Expand Down Expand Up @@ -307,8 +344,10 @@
"phoneme_duration": 120,
"multiplier": 1.0,
"energy_ratio": 1.5,
"wake_word": "hey mycroft",
"stand_up_word": "wake up",

// DEPRECATED, multiple hotwords are supported now, see "hotwords" section below
//"wake_word": "hey mycroft",
//"stand_up_word": "wake up",

// Settings used by microphone to set recording timeout
"recording_timeout": 10.0,
Expand All @@ -330,7 +369,7 @@
// Hotword configurations
"hotwords": {
"hey mycroft": {
"module": "precise",
"module": "ovos-precise-lite",
"phonemes": "HH EY . M AY K R AO F T",
"threshold": 1e-90,
"lang": "en-us",
Expand All @@ -344,30 +383,20 @@
},

"wake up": {
"module": "pocketsphinx",
"module": "ovos-ww-plugin-pocketsphinx",
"phonemes": "W EY K . AH P",
"threshold": 1e-20,
"lang": "en-us",
"wakeup": true
}
},

// Mark 1 enclosure settings
// Override: SYSTEM (e.g. Picroft)
// DEPRECATED: the concept of enclosure will no longer exist in ovos-core
// this has been replaced with PHAL
"enclosure": {
// Platform name
// Options: 'picroft', 'mycroft_mark_1'
// Override: SYSTEM (set by specific enclosures)
"platform": "OpenVoiceOS",
// "platform_enclosure_path": "/etc/myenclosure/code.py",

// COMM params to the Arduino/faceplate
"port": "/dev/ttyAMA0",
"rate": 9600,
"timeout": 5.0,

// ??
"update": true,

// The NTP sync should only forced on Raspberry Pi based devices.
"ntp_sync_on_boot": false,
Expand All @@ -376,10 +405,8 @@
// ('mycroft_mark_1', 'picroft', 'mycroft_mark_2pi')
// to disable forced ntp_sync in official mycroft platforms
// set this to false
"force_mycroft_ntp": true,
"force_mycroft_ntp": true

// Run a self test at bootup?
"test": false
},

// Level of logs to store, one of "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"
Expand Down Expand Up @@ -422,31 +449,8 @@
// Text to Speech parameters
// Override: REMOTE
"tts": {
// Engine. Options: "mimic", "mimic2", "google", "marytts", "fatts", "espeak",
// "spdsay", "responsive_voice", "yandex", "polly", "mozilla"
"pulse_duck": false,
"module": "mimic",
"polly": {
"voice": "Matthew",
"region": "us-east-1",
"access_key_id": "",
"secret_access_key": ""
},
"mimic": {
"voice": "ap"
},
"mimic2": {
"lang": "en-us",
"url": "https://mimic-api.mycroft.ai/synthesize?text=",
"preloaded_cache": "/opt/mycroft/preloaded_cache/Mimic2"
},
"espeak": {
"lang": "english-us",
"voice": "m1"
},
"mozilla": {
"url": "http://0.0.0.0:5002"
}
"module": "ovos-tts-plugin-mimic2"
},

"padatious": {
Expand Down

0 comments on commit 7532980

Please sign in to comment.