Skip to content

Commit

Permalink
command line shortcut for the permission setup
Browse files Browse the repository at this point in the history
  • Loading branch information
sezanzeb authored and sezanzeb committed Dec 5, 2020
1 parent 14f93fa commit 3940c57
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 15 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,11 @@ you can read information from your devices. You have to start the application
via sudo otherwise. You may also need to grant yourself write access to
`/dev/uinput` to be able to inject your programmed mapping.

There is a shortcut for configuring this stuff:

```bash
# either use sudo key-mapper-gtk or
sudo usermod -a -G plugdev,input $USER
sudo setfacl -m u:$USER:rw- /dev/uinput
# log out and back in or restart, the two groups should be visible with:
groups
sudo key-mapper-service --setup-permissions
# now log out and back in
```

##### Manjaro/Arch
Expand Down
48 changes: 48 additions & 0 deletions bin/key-mapper-service
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@


import sys
import os
import atexit
import grp
from argparse import ArgumentParser

import gi
Expand All @@ -35,9 +37,27 @@ from keymapper.logger import update_verbosity, log_info, \
add_filehandler, logger
from keymapper.daemon import Daemon, BUS_NAME
from keymapper.state import system_mapping
from keymapper.paths import USER
from keymapper.dev.permissions import can_read_devices


def run(cmd):
"""Run and log a command."""
logger.info('Running `%s`...', cmd)
code = os.system(cmd)
if code != 0:
logger.error('Failed. exit code %d', code)


def group_exists(name):
"""Check if a group with that name exists."""
try:
grp.getgrnam(name)
return True
except KeyError:
return False


if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument(
Expand All @@ -50,6 +70,14 @@ if __name__ == '__main__':
help='Print all available names for the mapping',
default=False
)
parser.add_argument(
'-s', '--setup-permissions', action='store_true', dest='setup',
help=(
'Requires sudo. Sets up all needed permissions to run'
'key-mapper as regular user'
),
default=False
)

options = parser.parse_args(sys.argv[1:])

Expand All @@ -62,6 +90,26 @@ if __name__ == '__main__':
print('\n'.join(system_mapping.list_names()))
sys.exit(0)

if options.setup:
if os.environ['USER'] != 'root' or USER == 'root':
# USER should contain the actual non-root user
logger.error('This only works using sudo')
sys.exit(1)

if group_exists('input'):
run('usermod -a -G input $USER')

if group_exists('plugdev'):
run('usermod -a -G plugdev $USER')

run('setfacl -m u:$USER:rw- /dev/uinput')

logger.info(
'For these changes to take effect log out and in. '
'In some environments you may need to reboot.'
)
sys.exit(0)

can_read_devices()

bus = SessionBus()
Expand Down
19 changes: 12 additions & 7 deletions keymapper/dev/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def check_group(group):
msg = (
'Some devices may not be visible without being in the '
f'"{group}" user group. Try `sudo usermod -a -G {group} {USER}` '
'and log out and back in or restart.',
'and log out and back in or restart.'
)
logger.warning(msg)
return msg
Expand All @@ -67,9 +67,8 @@ def check_group(group):
if in_group and not group_active:
msg = (
f'You are in the "{group}" group, but your session is not yet '
'using it. Some device may not be visible. Please log out and '
'back in or restart',
group
'using it. Some devices may not be visible. Please log out and '
'back in or restart'
)
logger.warning(msg)
return msg
Expand All @@ -80,12 +79,12 @@ def check_group(group):
def check_injection_rights():
"""Check if the user may write into /dev/uinput."""
if not os.access('/dev/uinput', os.W_OK):
can_write = (
msg = (
'Rights to write to /dev/uinput are missing, keycodes cannot '
f'be injected. Try `sudo setfacl -m u:{USER}:rw- /dev/uinput`'
)
logger.error(can_write)
return can_write
logger.error(msg)
return msg

return None

Expand All @@ -109,4 +108,10 @@ def can_read_devices():
if plugdev_check is not None:
ret.append(plugdev_check)

if len(ret) > 0:
logger.info(
'You can also use `sudo key-mapper-service --setup-permissions` '
'as a shortcut for mentioned commands.'
)

return ret
9 changes: 7 additions & 2 deletions keymapper/gtk/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,15 @@ def __init__(self):
permission_errors = can_read_devices()
if len(permission_errors) > 0:
# TODO test
permission_errors = [(
'You can also try `sudo key-mapper-service --setup-permiss'
'ions` to setup all needed permissions for you. All '
'commands mentioned here are also printed to the console '
'for you to copy.'
)] + permission_errors
self.show_status(
CTX_ERROR,
'Permission error. Hover for info',
'Permission error, hover for info',
'\n\n'.join(permission_errors)
)

Expand Down Expand Up @@ -288,7 +294,6 @@ def show_status(self, context_id, message, tooltip=None):

def check_macro_syntax(self):
"""Check if the programmed macros are allright."""
# test macros for syntax errors
# TODO test
for (ev_type, keycode), output in custom_mapping:
if not is_this_a_macro(output):
Expand Down
6 changes: 5 additions & 1 deletion keymapper/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
# failed in some ubuntu installations
USER = os.environ['USER']
if USER == 'root':
USER = os.environ.get('SUDO_USER', USER)
try:
USER = os.environ.get('SUDO_USER', USER)
except KeyError:
# no sudo was used
pass

CONFIG = os.path.join('/home', USER, '.config/key-mapper')

Expand Down

0 comments on commit 3940c57

Please sign in to comment.