mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
Use classic unix users rather than systemd dynamic users
Dynamic Users are neat and probably very useful for a tmpnb style situation. However, for regular use they have the following problems: 1. Can't set ProtectHome=no, so you can never apt install or similar from inside admin accounts. 2. Dynamic uid / gid makes it hard to write sudo rules. We want admin users to have sudo. 3. Persistent uids / gids are very useful for ad-hoc ACLs between users. gid sharing isn't the most flexible sharing mechanism, but it is well known & quite useful. 4. /etc/skel is pretty useful!
This commit is contained in:
123
tljh/user.py
Normal file
123
tljh/user.py
Normal file
@@ -0,0 +1,123 @@
|
||||
"""
|
||||
User management for tljh.
|
||||
|
||||
Supports user creation, deletion & sudo
|
||||
"""
|
||||
import pwd
|
||||
import grp
|
||||
import subprocess
|
||||
|
||||
|
||||
def ensure_user(username):
|
||||
"""
|
||||
Make sure a given user exists
|
||||
"""
|
||||
# Check if user exists
|
||||
try:
|
||||
pwd.getpwnam(username)
|
||||
# User exists, nothing to do!
|
||||
return
|
||||
except KeyError:
|
||||
# User doesn't exist, time to create!
|
||||
pass
|
||||
|
||||
subprocess.check_call([
|
||||
'sudo',
|
||||
'adduser',
|
||||
'--disabled-password',
|
||||
'--force-badname',
|
||||
'--quiet',
|
||||
username
|
||||
])
|
||||
|
||||
|
||||
def remove_user(username):
|
||||
"""
|
||||
Remove user from system if exists
|
||||
"""
|
||||
try:
|
||||
pwd.getpwnam(username)
|
||||
except KeyError:
|
||||
# User doesn't exist, nothing to do
|
||||
return
|
||||
|
||||
subprocess.check_call([
|
||||
'sudo',
|
||||
'deluser',
|
||||
'--quiet',
|
||||
username
|
||||
])
|
||||
|
||||
|
||||
def ensure_group(groupname):
|
||||
"""
|
||||
Ensure given group exists
|
||||
"""
|
||||
try:
|
||||
grp.getgrnam(groupname)
|
||||
# Group exists, nothing to do!
|
||||
return
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
subprocess.check_call([
|
||||
'sudo',
|
||||
'addgroup',
|
||||
'--quiet',
|
||||
groupname
|
||||
])
|
||||
|
||||
|
||||
def remove_group(groupname):
|
||||
"""
|
||||
Remove user from system if exists
|
||||
"""
|
||||
try:
|
||||
grp.getgrnam(groupname)
|
||||
except KeyError:
|
||||
# Group doesn't exist, nothing to do
|
||||
return
|
||||
|
||||
subprocess.check_call([
|
||||
'sudo',
|
||||
'delgroup',
|
||||
'--quiet',
|
||||
groupname
|
||||
])
|
||||
|
||||
|
||||
def ensure_user_group(username, groupname):
|
||||
"""
|
||||
Ensure given user is member of given group
|
||||
|
||||
Group and User must already exist.
|
||||
"""
|
||||
group = grp.getgrnam(groupname)
|
||||
if username in group.gr_mem:
|
||||
return
|
||||
|
||||
subprocess.check_call([
|
||||
'sudo',
|
||||
'usermod',
|
||||
'--append',
|
||||
'--groups',
|
||||
groupname,
|
||||
username
|
||||
])
|
||||
|
||||
|
||||
def remove_user_group(username, groupname):
|
||||
"""
|
||||
Ensure given user is *not* a member of given group
|
||||
"""
|
||||
group = grp.getgrnam(groupname)
|
||||
if username not in group.gr_mem:
|
||||
return
|
||||
|
||||
subprocess.check_call([
|
||||
'sudo',
|
||||
'deluser',
|
||||
'--quiet',
|
||||
username,
|
||||
groupname
|
||||
])
|
||||
Reference in New Issue
Block a user