use snapd apis to check for a user and (minimally) handle a managed system with no owner

This commit is contained in:
Michael Hudson-Doyle 2020-07-03 15:35:32 +12:00
parent 9271f17dd2
commit 164c575f2a
2 changed files with 57 additions and 37 deletions

View File

@ -16,11 +16,13 @@
import json
import logging
import os
import pwd
import shlex
import sys
from subiquitycore.controller import BaseController
from subiquitycore.ssh import host_key_info, get_ips_standalone
from subiquitycore.snapd import SnapdConnection
from subiquitycore.utils import disable_console_conf, run_command
from console_conf.ui.views import IdentityView, LoginView
@ -50,24 +52,31 @@ def get_core_version():
return version
def get_device_owner():
""" Check if device is owned """
def get_managed():
""" Check if device is managed """
con = SnapdConnection('', '/run/snapd.socket')
return con.get('v2/system-info').json()['result']['managed']
# TODO: use proper snap APIs.
def get_realname(username):
try:
extrausers_fp = open('/var/lib/extrausers/passwd', 'r')
except FileNotFoundError:
return None
with extrausers_fp:
passwd_line = extrausers_fp.readline()
if passwd_line and len(passwd_line) > 0:
passwd = passwd_line.split(':')
result = {
'realname': passwd[4].split(',')[0],
'username': passwd[0],
'homedir': passwd[5],
info = pwd.getpwnam(username)
except KeyError:
return ''
return info.pw_gecos.split(',', 1)[0]
def get_device_owner():
""" Get device owner, if any """
con = SnapdConnection('', '/run/snapd.socket')
for user in con.get('v2/users').json()['result']:
user = user['email'].split('@')[0]
if os.path.isdir('/home/' + user):
return {
'username': user,
'realname': get_realname(user),
'homedir': '/home/' + user,
}
return result
return None
@ -111,17 +120,21 @@ def write_login_details(fp, username, ips):
def write_login_details_standalone():
owner = get_device_owner()
if owner is None:
print("No device owner details found.")
return 0
ips = get_ips_standalone()
if len(ips) == 0:
tty_name = os.ttyname(0)[5:]
version = get_core_version() or "16"
print(login_details_tmpl_no_ip.format(tty_name=tty_name,
version=version))
return 2
write_login_details(sys.stdout, owner['username'], ips)
if owner is None:
print("device managed without user")
return 2
else:
tty_name = os.ttyname(0)[5:]
version = get_core_version() or "16"
print(login_details_tmpl_no_ip.format(
tty_name=tty_name, version=version))
return 2
if owner is None:
print("device managed without user @ {}".format(', '.join(ips)))
else:
write_login_details(sys.stdout, owner['username'], ips)
return 0
@ -133,14 +146,15 @@ class IdentityController(BaseController):
def start_ui(self):
self.ui.set_body(IdentityView(self.model, self))
device_owner = get_device_owner()
if device_owner is not None:
self.model.add_user(device_owner)
key_file = os.path.join(device_owner['homedir'],
".ssh/authorized_keys")
self.model.user.fingerprints = (
run_command(['ssh-keygen', '-lf',
key_file]).stdout.replace('\r', '').splitlines())
if get_managed():
device_owner = get_device_owner()
if device_owner:
self.model.add_user(device_owner)
key_file = os.path.join(device_owner['homedir'],
".ssh/authorized_keys")
cp = run_command(['ssh-keygen', '-lf', key_file])
self.model.user.fingerprints = (
cp.stdout.replace('\r', '').splitlines())
self.login()
def identity_done(self, email):

View File

@ -57,6 +57,17 @@ class LoginView(BaseView):
]
def _build_model_inputs(self):
user = self.model.user
ips = []
for dev in self.netdevs:
for addr in dev.actual_global_ip_addresses:
ips.append(addr)
if not user:
sl = []
sl.append(Text("no owner"))
return sl
local_tpl = (
"This device is registered to {realname}.")
@ -67,17 +78,12 @@ class LoginView(BaseView):
"device via SSH:")
sl = []
user = self.model.user
login_info = {
'realname': user.realname,
'username': user.username,
}
login_text = local_tpl.format(**login_info)
login_text += remote_tpl.format(**login_info)
ips = []
for dev in self.netdevs:
for addr in dev.actual_global_ip_addresses:
ips.append(addr)
sl += [Text(login_text), Padding.line_break("")]
for ip in ips: