{-# LANGUAGE DeriveDataTypeable, TypeFamilies #-}

module Propellor.Property.Ssh (
	installed,
	restarted,
	PubKeyText,
	SshKeyType(..),
	-- * Daemon configuration
	sshdConfig,
	ConfigKeyword,
	setSshdConfigBool,
	setSshdConfig,
	RootLogin(..),
	permitRootLogin,
	passwordAuthentication,
	noPasswords,
	listenPort,
	-- * Host keys
	randomHostKeys,
	hostKeys,
	hostKey,
	hostPubKey,
	getHostPubKey,
	-- * User keys and configuration
	userKeys,
	userKeyAt,
	knownHost,
	unknownHost,
	authorizedKeysFrom,
	unauthorizedKeysFrom,
	authorizedKeys,
	authorizedKey,
	hasAuthorizedKeys,
	getUserPubKeys,
) where

import Propellor.Base
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Service as Service
import qualified Propellor.Property.Apt as Apt
import Propellor.Property.User
import Propellor.Types.Info

import System.Posix.User
import System.Posix.Files
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Semigroup as Sem
import Data.List

installed :: Property UnixLike
installed :: Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
installed = PubKeyText
"ssh installed" PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall i.
IsProp (Property i) =>
PubKeyText -> Property i -> Property i
==> (Property DebianLike
aptinstall Property DebianLike
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} ka kb (c :: k) (a :: ka) (b :: kb).
(HasCallStack, SingKind 'KProxy, SingKind 'KProxy,
 DemoteRep 'KProxy ~ [MetaType], DemoteRep 'KProxy ~ [MetaType],
 SingI c) =>
Property (MetaTypes a)
-> Property (MetaTypes b) -> Property (MetaTypes c)
`pickOS` Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
unsupportedOS)
  where
	aptinstall :: Property DebianLike
	aptinstall :: Property DebianLike
aptinstall = [PubKeyText] -> Property DebianLike
Apt.installed [PubKeyText
"ssh"]

restarted :: Property DebianLike
restarted :: Property DebianLike
restarted = PubKeyText -> Property DebianLike
Service.restarted PubKeyText
"ssh"

sshBool :: Bool -> String
sshBool :: Bool -> PubKeyText
sshBool Bool
True = PubKeyText
"yes"
sshBool Bool
False = PubKeyText
"no"

sshdConfig :: FilePath
sshdConfig :: PubKeyText
sshdConfig = PubKeyText
"/etc/ssh/sshd_config"

type ConfigKeyword = String

setSshdConfigBool :: ConfigKeyword -> Bool -> Property DebianLike
setSshdConfigBool :: PubKeyText -> Bool -> Property DebianLike
setSshdConfigBool PubKeyText
setting Bool
allowed = PubKeyText -> PubKeyText -> Property DebianLike
setSshdConfig PubKeyText
setting (Bool -> PubKeyText
sshBool Bool
allowed)

setSshdConfig :: ConfigKeyword -> String -> Property DebianLike
setSshdConfig :: PubKeyText -> PubKeyText -> Property DebianLike
setSshdConfig PubKeyText
setting PubKeyText
v = PubKeyText
-> ([PubKeyText] -> [PubKeyText])
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall c.
(FileContent c, Eq c) =>
PubKeyText
-> (c -> c)
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.fileProperty PubKeyText
desc [PubKeyText] -> [PubKeyText]
f PubKeyText
sshdConfig
	Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property DebianLike
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property DebianLike
restarted
  where
	desc :: PubKeyText
desc = [PubKeyText] -> PubKeyText
unwords [ PubKeyText
"ssh config:", PubKeyText
setting, PubKeyText
v ]
	cfgline :: PubKeyText
cfgline = PubKeyText
setting PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
v
	wantedline :: PubKeyText -> Bool
wantedline PubKeyText
s
		| PubKeyText
s PubKeyText -> PubKeyText -> Bool
forall a. Eq a => a -> a -> Bool
== PubKeyText
cfgline = Bool
True
		| (PubKeyText
setting PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" ") PubKeyText -> PubKeyText -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` PubKeyText
s = Bool
False
		| Bool
otherwise = Bool
True
	f :: [PubKeyText] -> [PubKeyText]
f [PubKeyText]
ls
		| PubKeyText
cfgline PubKeyText -> [PubKeyText] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PubKeyText]
ls = (PubKeyText -> Bool) -> [PubKeyText] -> [PubKeyText]
forall a. (a -> Bool) -> [a] -> [a]
filter PubKeyText -> Bool
wantedline [PubKeyText]
ls
		| Bool
otherwise = (PubKeyText -> Bool) -> [PubKeyText] -> [PubKeyText]
forall a. (a -> Bool) -> [a] -> [a]
filter PubKeyText -> Bool
wantedline [PubKeyText]
ls [PubKeyText] -> [PubKeyText] -> [PubKeyText]
forall a. [a] -> [a] -> [a]
++ [PubKeyText
cfgline]

data RootLogin
	= RootLogin Bool  -- ^ allow or prevent root login
	| WithoutPassword -- ^ disable password authentication for root, while allowing other authentication methods
	| ForcedCommandsOnly -- ^ allow root login with public-key authentication, but only if a forced command has been specified for the public key

permitRootLogin :: RootLogin -> Property DebianLike
permitRootLogin :: RootLogin -> Property DebianLike
permitRootLogin (RootLogin Bool
b) = PubKeyText -> Bool -> Property DebianLike
setSshdConfigBool PubKeyText
"PermitRootLogin" Bool
b
permitRootLogin RootLogin
WithoutPassword = PubKeyText -> PubKeyText -> Property DebianLike
setSshdConfig PubKeyText
"PermitRootLogin" PubKeyText
"without-password"
permitRootLogin RootLogin
ForcedCommandsOnly = PubKeyText -> PubKeyText -> Property DebianLike
setSshdConfig PubKeyText
"PermitRootLogin" PubKeyText
"forced-commands-only"

passwordAuthentication :: Bool -> Property DebianLike
passwordAuthentication :: Bool -> Property DebianLike
passwordAuthentication = PubKeyText -> Bool -> Property DebianLike
setSshdConfigBool PubKeyText
"PasswordAuthentication"

-- | Configure ssh to not allow password logins.
--
-- To prevent lock-out, this is done only once root's
-- authorized_keys is in place.
noPasswords :: Property DebianLike
noPasswords :: Property DebianLike
noPasswords = IO Bool -> Property DebianLike -> Property DebianLike
forall (p :: * -> *) i (m :: * -> *).
(Checkable p i, LiftPropellor m) =>
m Bool -> p i -> Property i
check (User -> IO Bool
hasAuthorizedKeys (PubKeyText -> User
User PubKeyText
"root")) (Property DebianLike -> Property DebianLike)
-> Property DebianLike -> Property DebianLike
forall a b. (a -> b) -> a -> b
$
	Bool -> Property DebianLike
passwordAuthentication Bool
False

dotDir :: User -> IO FilePath
dotDir :: User -> IO PubKeyText
dotDir User
user = do
	PubKeyText
h <- User -> IO PubKeyText
homedir User
user
	PubKeyText -> IO PubKeyText
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKeyText -> IO PubKeyText) -> PubKeyText -> IO PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText
h PubKeyText -> PubKeyText -> PubKeyText
</> PubKeyText
".ssh"

dotFile :: FilePath -> User -> IO FilePath
dotFile :: PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
f User
user = do
	PubKeyText
d <- User -> IO PubKeyText
dotDir User
user
	PubKeyText -> IO PubKeyText
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKeyText -> IO PubKeyText) -> PubKeyText -> IO PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText
d PubKeyText -> PubKeyText -> PubKeyText
</> PubKeyText
f

-- | Makes the ssh server listen on a given port, in addition to any other
-- ports it is configured to listen on.
--
-- Revert to prevent it listening on a particular port.
listenPort :: Port -> RevertableProperty DebianLike DebianLike
listenPort :: Port -> RevertableProperty DebianLike DebianLike
listenPort Port
port = CombinedType
  (Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
  (Property DebianLike)
Property DebianLike
enable Property DebianLike
-> Property DebianLike -> RevertableProperty DebianLike DebianLike
forall setupmetatypes undometatypes.
Property setupmetatypes
-> Property undometatypes
-> RevertableProperty setupmetatypes undometatypes
<!> CombinedType
  (Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
  (Property DebianLike)
Property DebianLike
disable
  where
	portline :: PubKeyText
portline = PubKeyText
"Port " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ Port -> PubKeyText
forall t. ConfigurableValue t => t -> PubKeyText
val Port
port
	enable :: CombinedType
  (Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
  (Property DebianLike)
enable = PubKeyText
sshdConfig PubKeyText
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`File.containsLine` PubKeyText
portline
		Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall p. IsProp p => p -> PubKeyText -> p
`describe` (PubKeyText
"ssh listening on " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
portline)
		Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property DebianLike
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property DebianLike
restarted
	disable :: CombinedType
  (Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
  (Property DebianLike)
disable = PubKeyText
sshdConfig PubKeyText
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`File.lacksLine` PubKeyText
portline
		Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall p. IsProp p => p -> PubKeyText -> p
`describe` (PubKeyText
"ssh not listening on " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
portline)
		Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property DebianLike
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property DebianLike
restarted

hasAuthorizedKeys :: User -> IO Bool
hasAuthorizedKeys :: User -> IO Bool
hasAuthorizedKeys = PubKeyText -> IO Bool
go (PubKeyText -> IO Bool)
-> (User -> IO PubKeyText) -> User -> IO Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
"authorized_keys"
  where
	go :: PubKeyText -> IO Bool
go PubKeyText
f = Bool -> Bool
not (Bool -> Bool) -> (PubKeyText -> Bool) -> PubKeyText -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKeyText -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (PubKeyText -> Bool) -> IO PubKeyText -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PubKeyText -> IO PubKeyText -> IO PubKeyText
forall (m :: * -> *) a. MonadCatch m => a -> m a -> m a
catchDefaultIO PubKeyText
"" (PubKeyText -> IO PubKeyText
readFile PubKeyText
f)

-- | Blows away existing host keys and make new ones.
-- Useful for systems installed from an image that might reuse host keys.
-- A flag file is used to only ever do this once.
randomHostKeys :: Property DebianLike
randomHostKeys :: Property DebianLike
randomHostKeys = Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall i. Property i -> PubKeyText -> Property i
flagFile Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
prop PubKeyText
"/etc/ssh/.unique_host_keys"
	Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property DebianLike
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property DebianLike
restarted
  where
	prop :: Property UnixLike
	prop :: Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
prop = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
"ssh random host keys" ((OuterMetaTypesWitness
    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> do
		Propellor Bool -> Propellor ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Propellor Bool -> Propellor ()) -> Propellor Bool -> Propellor ()
forall a b. (a -> b) -> a -> b
$ IO Bool -> Propellor Bool
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> Propellor Bool) -> IO Bool -> Propellor Bool
forall a b. (a -> b) -> a -> b
$ PubKeyText -> [CommandParam] -> IO Bool
boolSystem PubKeyText
"sh"
			[ PubKeyText -> CommandParam
Param PubKeyText
"-c"
			, PubKeyText -> CommandParam
Param PubKeyText
"rm -f /etc/ssh/ssh_host_*"
			]
		OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ [PubKeyText]
-> UncheckedProperty
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
scriptProperty [ PubKeyText
"DPKG_MAINTSCRIPT_NAME=postinst DPKG_MAINTSCRIPT_PACKAGE=openssh-server /var/lib/dpkg/info/openssh-server.postinst configure" ]
			UncheckedProperty
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Result
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall (p :: * -> *) i.
Checkable p i =>
p i -> Result -> Property i
`assume` Result
MadeChange

-- | The text of a ssh public key, for example, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3BJ2GqZiTR2LEoDXyYFgh/BduWefjdKXAsAtzS9zeI"
type PubKeyText = String

-- | Installs the specified list of ssh host keys.
--
-- The corresponding private keys come from the privdata.
--
-- Any host keys that are not in the list are removed from the host.
hostKeys :: IsContext c => c -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + DebianLike)
hostKeys :: forall c.
IsContext c =>
c -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + DebianLike)
hostKeys c
ctx [(SshKeyType, PubKeyText)]
l = Property
  (MetaTypes
     '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
Property (HasInfo + DebianLike)
go Property
  (MetaTypes
     '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
-> Property DebianLike
-> CombinedType
     (Property
        (MetaTypes
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
     (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`before` Property DebianLike
cleanup
  where
	desc :: PubKeyText
desc = PubKeyText
"ssh host keys configured " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ [SshKeyType] -> PubKeyText
typelist (((SshKeyType, PubKeyText) -> SshKeyType)
-> [(SshKeyType, PubKeyText)] -> [SshKeyType]
forall a b. (a -> b) -> [a] -> [b]
map (SshKeyType, PubKeyText) -> SshKeyType
forall a b. (a, b) -> a
fst [(SshKeyType, PubKeyText)]
l)
	go :: Property (HasInfo + DebianLike)
	go :: Property (HasInfo + DebianLike)
go = PubKeyText
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
propertyList PubKeyText
desc (Props
   (MetaTypes
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
forall a b. (a -> b) -> a -> b
$ [Property
   (MetaTypes
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])]
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
forall {k} (metatypes :: k).
[Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes)
toProps ([Property
    (MetaTypes
       '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])]
 -> Props
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])]
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
forall a b. (a -> b) -> a -> b
$ [Maybe
   (Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))]
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe
    (Property
       (MetaTypes
          '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))]
 -> [Property
       (MetaTypes
          '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])])
-> [Maybe
      (Property
         (MetaTypes
            '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))]
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])]
forall a b. (a -> b) -> a -> b
$
		((SshKeyType, PubKeyText)
 -> Maybe
      (Property
         (MetaTypes
            '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])))
-> [(SshKeyType, PubKeyText)]
-> [Maybe
      (Property
         (MetaTypes
            '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))]
forall a b. (a -> b) -> [a] -> [b]
map (\(SshKeyType
t, PubKeyText
pub) -> Property (HasInfo + DebianLike)
-> Maybe (Property (HasInfo + DebianLike))
forall a. a -> Maybe a
Just (Property (HasInfo + DebianLike)
 -> Maybe (Property (HasInfo + DebianLike)))
-> Property (HasInfo + DebianLike)
-> Maybe (Property (HasInfo + DebianLike))
forall a b. (a -> b) -> a -> b
$ c -> SshKeyType -> PubKeyText -> Property (HasInfo + DebianLike)
forall c.
IsContext c =>
c -> SshKeyType -> PubKeyText -> Property (HasInfo + DebianLike)
hostKey c
ctx SshKeyType
t PubKeyText
pub) [(SshKeyType, PubKeyText)]
l
	typelist :: [SshKeyType] -> PubKeyText
typelist [SshKeyType]
tl = PubKeyText
"(" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ [PubKeyText] -> PubKeyText
unwords ((SshKeyType -> PubKeyText) -> [SshKeyType] -> [PubKeyText]
forall a b. (a -> b) -> [a] -> [b]
map SshKeyType -> PubKeyText
fromKeyType [SshKeyType]
tl) PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
")"
	alltypes :: [SshKeyType]
alltypes = [SshKeyType
forall a. Bounded a => a
minBound..SshKeyType
forall a. Bounded a => a
maxBound]
	staletypes :: [SshKeyType]
staletypes = let have :: [SshKeyType]
have = ((SshKeyType, PubKeyText) -> SshKeyType)
-> [(SshKeyType, PubKeyText)] -> [SshKeyType]
forall a b. (a -> b) -> [a] -> [b]
map (SshKeyType, PubKeyText) -> SshKeyType
forall a b. (a, b) -> a
fst [(SshKeyType, PubKeyText)]
l in (SshKeyType -> Bool) -> [SshKeyType] -> [SshKeyType]
forall a. (a -> Bool) -> [a] -> [a]
filter (SshKeyType -> [SshKeyType] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [SshKeyType]
have) [SshKeyType]
alltypes
	removestale :: Bool -> [Property DebianLike]
	removestale :: Bool -> [Property DebianLike]
removestale Bool
b = (SshKeyType -> Property DebianLike)
-> [SshKeyType] -> [Property DebianLike]
forall a b. (a -> b) -> [a] -> [b]
map (Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property DebianLike
forall (untightened :: [MetaType]) (tightened :: [MetaType]).
(TightenTargetsAllowed untightened tightened, SingI tightened) =>
Property (MetaTypes untightened) -> Property (MetaTypes tightened)
forall (p :: * -> *) (untightened :: [MetaType])
       (tightened :: [MetaType]).
(TightenTargets p, TightenTargetsAllowed untightened tightened,
 SingI tightened) =>
p (MetaTypes untightened) -> p (MetaTypes tightened)
tightenTargets (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property DebianLike)
-> (SshKeyType
    -> Property
         (MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> SshKeyType
-> Property DebianLike
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.notPresent (PubKeyText
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (SshKeyType -> PubKeyText)
-> SshKeyType
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SshKeyType -> Bool -> PubKeyText)
-> Bool -> SshKeyType -> PubKeyText
forall a b c. (a -> b -> c) -> b -> a -> c
flip SshKeyType -> Bool -> PubKeyText
keyFile Bool
b) [SshKeyType]
staletypes
	cleanup :: Property DebianLike
	cleanup :: Property DebianLike
cleanup
		| [SshKeyType] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SshKeyType]
staletypes Bool -> Bool -> Bool
|| [(SshKeyType, PubKeyText)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(SshKeyType, PubKeyText)]
l = Property DebianLike
forall {k} (t :: k). SingI t => Property (MetaTypes t)
doNothing
		| Bool
otherwise =
			PubKeyText -> Props DebianLike -> Property DebianLike
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties (PubKeyText
"any other ssh host keys removed " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ [SshKeyType] -> PubKeyText
typelist [SshKeyType]
staletypes)
				([Property DebianLike] -> Props DebianLike
forall {k} (metatypes :: k).
[Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes)
toProps ([Property DebianLike] -> Props DebianLike)
-> [Property DebianLike] -> Props DebianLike
forall a b. (a -> b) -> a -> b
$ Bool -> [Property DebianLike]
removestale Bool
True [Property DebianLike]
-> [Property DebianLike] -> [Property DebianLike]
forall a. [a] -> [a] -> [a]
++ Bool -> [Property DebianLike]
removestale Bool
False)
				Property DebianLike
-> Property DebianLike
-> CombinedType (Property DebianLike) (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property DebianLike
restarted

-- | Installs a single ssh host key of a particular type.
--
-- The public key is provided to this function;
-- the private key comes from the privdata;
hostKey :: IsContext c => c -> SshKeyType -> PubKeyText -> Property (HasInfo + DebianLike)
hostKey :: forall c.
IsContext c =>
c -> SshKeyType -> PubKeyText -> Property (HasInfo + DebianLike)
hostKey c
context SshKeyType
keytype PubKeyText
pub = Property
  (MetaTypes
     (Combine
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
go Property
  (MetaTypes
     (Combine
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property DebianLike
-> CombinedType
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
     (Property DebianLike)
forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property DebianLike
restarted
  where
	go :: Property
  (MetaTypes
     (Combine
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
go = PubKeyText
-> Props
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (MetaTypes
      (Combine
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Property
      (MetaTypes
         (Combine
            (Combine
               (Combine
                  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
-> Props
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall a b. (a -> b) -> a -> b
$ Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
props
		Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (Sing
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& SshKeyType
-> PubKeyText
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
hostPubKey SshKeyType
keytype PubKeyText
pub
		Props
  (Sing
     (Combine
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
installpub
		Props
  (Sing
     (Combine
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property
  (MetaTypes
     '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
Property
  (HasInfo
   + MetaTypes
       '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
installpriv
	desc :: PubKeyText
desc = PubKeyText
"ssh host key configured (" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ SshKeyType -> PubKeyText
fromKeyType SshKeyType
keytype PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
")"
	keysrc :: PubKeyText -> PrivDataField -> PrivDataSource
keysrc PubKeyText
ext PrivDataField
field = PrivDataField -> PubKeyText -> PubKeyText -> PrivDataSource
PrivDataSourceFileFromCommand PrivDataField
field (PubKeyText
"sshkey"PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++PubKeyText
ext)
		(PubKeyText
"ssh-keygen -t " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ SshKeyType -> PubKeyText
sshKeyTypeParam SshKeyType
keytype PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" -f sshkey")
	installpub :: Property UnixLike
	installpub :: Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
installpub = (PubKeyText
 -> [PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Bool
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
keywriter PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.hasContent Bool
True (PubKeyText -> [PubKeyText]
lines PubKeyText
pub)
	installpriv :: Property (HasInfo + UnixLike)
	installpriv :: Property
  (HasInfo
   + MetaTypes
       '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
installpriv = PrivDataSource
-> c
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property
         (HasInfo
          + MetaTypes
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall c s metatypes.
(IsContext c, IsPrivDataSource s,
 IncludesInfo metatypes ~ 'True) =>
s
-> c
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property metatypes)
-> Property metatypes
withPrivData (PubKeyText -> PrivDataField -> PrivDataSource
keysrc PubKeyText
"" (SshKeyType -> PubKeyText -> PrivDataField
SshPrivKey SshKeyType
keytype PubKeyText
"")) c
context ((((PrivData -> Propellor Result) -> Propellor Result)
  -> Property
       (HasInfo
        + MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Property
      (HasInfo
       + MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property
         (HasInfo
          + MetaTypes
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \(PrivData -> Propellor Result) -> Propellor Result
getkey ->
		PubKeyText
-> (OuterMetaTypesWitness
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc ((OuterMetaTypesWitness
    '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> (PrivData -> Propellor Result) -> Propellor Result
getkey ((PrivData -> Propellor Result) -> Propellor Result)
-> (PrivData -> Propellor Result) -> Propellor Result
forall a b. (a -> b) -> a -> b
$
			OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w
				(Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> (PrivData
    -> Property
         (MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> PrivData
-> Propellor Result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PubKeyText
 -> [PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Bool
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
keywriter PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.hasContentProtected Bool
False
				([PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (PrivData -> [PubKeyText])
-> PrivData
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivData -> [PubKeyText]
privDataLines
	keywriter :: (PubKeyText
 -> [PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Bool
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
keywriter PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
p Bool
ispub [PubKeyText]
keylines = do
		let f :: PubKeyText
f = SshKeyType -> Bool -> PubKeyText
keyFile SshKeyType
keytype Bool
ispub
		PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
p PubKeyText
f ([PubKeyText] -> [PubKeyText]
keyFileContent [PubKeyText]
keylines)

-- Make sure that there is a newline at the end;
-- ssh requires this for some types of private keys.
keyFileContent :: [String] -> [File.Line]
keyFileContent :: [PubKeyText] -> [PubKeyText]
keyFileContent [PubKeyText]
keylines = [PubKeyText]
keylines [PubKeyText] -> [PubKeyText] -> [PubKeyText]
forall a. [a] -> [a] -> [a]
++ [PubKeyText
""]

keyFile :: SshKeyType -> Bool -> FilePath
keyFile :: SshKeyType -> Bool -> PubKeyText
keyFile SshKeyType
keytype Bool
ispub = PubKeyText
"/etc/ssh/ssh_host_" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ SshKeyType -> PubKeyText
fromKeyType SshKeyType
keytype PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
"_key" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
ext
  where
	ext :: PubKeyText
ext = if Bool
ispub then PubKeyText
".pub" else PubKeyText
""

-- | Indicates the host key that is used by a Host, but does not actually
-- configure the host to use it. Normally this does not need to be used;
-- use 'hostKey' instead.
hostPubKey :: SshKeyType -> PubKeyText -> Property (HasInfo + UnixLike)
hostPubKey :: SshKeyType
-> PubKeyText
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
hostPubKey SshKeyType
t = PubKeyText
-> HostKeyInfo
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall v.
IsInfo v =>
PubKeyText
-> v
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
pureInfoProperty PubKeyText
"ssh pubkey known" (HostKeyInfo
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (PubKeyText -> HostKeyInfo)
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map SshKeyType PubKeyText -> HostKeyInfo
HostKeyInfo (Map SshKeyType PubKeyText -> HostKeyInfo)
-> (PubKeyText -> Map SshKeyType PubKeyText)
-> PubKeyText
-> HostKeyInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SshKeyType -> PubKeyText -> Map SshKeyType PubKeyText
forall k a. k -> a -> Map k a
M.singleton SshKeyType
t

getHostPubKey :: Propellor (M.Map SshKeyType PubKeyText)
getHostPubKey :: Propellor (Map SshKeyType PubKeyText)
getHostPubKey = HostKeyInfo -> Map SshKeyType PubKeyText
fromHostKeyInfo (HostKeyInfo -> Map SshKeyType PubKeyText)
-> Propellor HostKeyInfo -> Propellor (Map SshKeyType PubKeyText)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Propellor HostKeyInfo
forall v. IsInfo v => Propellor v
askInfo

newtype HostKeyInfo = HostKeyInfo
	{ HostKeyInfo -> Map SshKeyType PubKeyText
fromHostKeyInfo :: M.Map SshKeyType PubKeyText }
	deriving (HostKeyInfo -> HostKeyInfo -> Bool
(HostKeyInfo -> HostKeyInfo -> Bool)
-> (HostKeyInfo -> HostKeyInfo -> Bool) -> Eq HostKeyInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: HostKeyInfo -> HostKeyInfo -> Bool
== :: HostKeyInfo -> HostKeyInfo -> Bool
$c/= :: HostKeyInfo -> HostKeyInfo -> Bool
/= :: HostKeyInfo -> HostKeyInfo -> Bool
Eq, Eq HostKeyInfo
Eq HostKeyInfo
-> (HostKeyInfo -> HostKeyInfo -> Ordering)
-> (HostKeyInfo -> HostKeyInfo -> Bool)
-> (HostKeyInfo -> HostKeyInfo -> Bool)
-> (HostKeyInfo -> HostKeyInfo -> Bool)
-> (HostKeyInfo -> HostKeyInfo -> Bool)
-> (HostKeyInfo -> HostKeyInfo -> HostKeyInfo)
-> (HostKeyInfo -> HostKeyInfo -> HostKeyInfo)
-> Ord HostKeyInfo
HostKeyInfo -> HostKeyInfo -> Bool
HostKeyInfo -> HostKeyInfo -> Ordering
HostKeyInfo -> HostKeyInfo -> HostKeyInfo
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: HostKeyInfo -> HostKeyInfo -> Ordering
compare :: HostKeyInfo -> HostKeyInfo -> Ordering
$c< :: HostKeyInfo -> HostKeyInfo -> Bool
< :: HostKeyInfo -> HostKeyInfo -> Bool
$c<= :: HostKeyInfo -> HostKeyInfo -> Bool
<= :: HostKeyInfo -> HostKeyInfo -> Bool
$c> :: HostKeyInfo -> HostKeyInfo -> Bool
> :: HostKeyInfo -> HostKeyInfo -> Bool
$c>= :: HostKeyInfo -> HostKeyInfo -> Bool
>= :: HostKeyInfo -> HostKeyInfo -> Bool
$cmax :: HostKeyInfo -> HostKeyInfo -> HostKeyInfo
max :: HostKeyInfo -> HostKeyInfo -> HostKeyInfo
$cmin :: HostKeyInfo -> HostKeyInfo -> HostKeyInfo
min :: HostKeyInfo -> HostKeyInfo -> HostKeyInfo
Ord, Typeable, Int -> HostKeyInfo -> PubKeyText -> PubKeyText
[HostKeyInfo] -> PubKeyText -> PubKeyText
HostKeyInfo -> PubKeyText
(Int -> HostKeyInfo -> PubKeyText -> PubKeyText)
-> (HostKeyInfo -> PubKeyText)
-> ([HostKeyInfo] -> PubKeyText -> PubKeyText)
-> Show HostKeyInfo
forall a.
(Int -> a -> PubKeyText -> PubKeyText)
-> (a -> PubKeyText) -> ([a] -> PubKeyText -> PubKeyText) -> Show a
$cshowsPrec :: Int -> HostKeyInfo -> PubKeyText -> PubKeyText
showsPrec :: Int -> HostKeyInfo -> PubKeyText -> PubKeyText
$cshow :: HostKeyInfo -> PubKeyText
show :: HostKeyInfo -> PubKeyText
$cshowList :: [HostKeyInfo] -> PubKeyText -> PubKeyText
showList :: [HostKeyInfo] -> PubKeyText -> PubKeyText
Show)

instance IsInfo HostKeyInfo where
	propagateInfo :: HostKeyInfo -> PropagateInfo
propagateInfo HostKeyInfo
_ = Bool -> PropagateInfo
PropagateInfo Bool
False

instance Sem.Semigroup HostKeyInfo where
	HostKeyInfo Map SshKeyType PubKeyText
old <> :: HostKeyInfo -> HostKeyInfo -> HostKeyInfo
<> HostKeyInfo Map SshKeyType PubKeyText
new =
		-- new first because union prefers values from the first
		-- parameter when there is a duplicate key
		Map SshKeyType PubKeyText -> HostKeyInfo
HostKeyInfo (Map SshKeyType PubKeyText
new Map SshKeyType PubKeyText
-> Map SshKeyType PubKeyText -> Map SshKeyType PubKeyText
forall k a. Ord k => Map k a -> Map k a -> Map k a
`M.union` Map SshKeyType PubKeyText
old)

instance Monoid HostKeyInfo where
	mempty :: HostKeyInfo
mempty = Map SshKeyType PubKeyText -> HostKeyInfo
HostKeyInfo Map SshKeyType PubKeyText
forall k a. Map k a
M.empty
	mappend :: HostKeyInfo -> HostKeyInfo -> HostKeyInfo
mappend = HostKeyInfo -> HostKeyInfo -> HostKeyInfo
forall a. Semigroup a => a -> a -> a
(Sem.<>)

userPubKeys :: User -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + UnixLike)
userPubKeys :: User
-> [(SshKeyType, PubKeyText)]
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
userPubKeys u :: User
u@(User PubKeyText
n) [(SshKeyType, PubKeyText)]
l = PubKeyText
-> UserKeyInfo
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall v.
IsInfo v =>
PubKeyText
-> v
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
pureInfoProperty (PubKeyText
"ssh pubkey for " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
n) (UserKeyInfo
 -> Property
      (HasInfo
       + MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> UserKeyInfo
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
	Map User (Set (SshKeyType, PubKeyText)) -> UserKeyInfo
UserKeyInfo (User
-> Set (SshKeyType, PubKeyText)
-> Map User (Set (SshKeyType, PubKeyText))
forall k a. k -> a -> Map k a
M.singleton User
u ([(SshKeyType, PubKeyText)] -> Set (SshKeyType, PubKeyText)
forall a. Ord a => [a] -> Set a
S.fromList [(SshKeyType, PubKeyText)]
l))

getUserPubKeys :: User -> Propellor [(SshKeyType, PubKeyText)]
getUserPubKeys :: User -> Propellor [(SshKeyType, PubKeyText)]
getUserPubKeys User
u = [(SshKeyType, PubKeyText)]
-> (Set (SshKeyType, PubKeyText) -> [(SshKeyType, PubKeyText)])
-> Maybe (Set (SshKeyType, PubKeyText))
-> [(SshKeyType, PubKeyText)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Set (SshKeyType, PubKeyText) -> [(SshKeyType, PubKeyText)]
forall a. Set a -> [a]
S.toList (Maybe (Set (SshKeyType, PubKeyText))
 -> [(SshKeyType, PubKeyText)])
-> (UserKeyInfo -> Maybe (Set (SshKeyType, PubKeyText)))
-> UserKeyInfo
-> [(SshKeyType, PubKeyText)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. User
-> Map User (Set (SshKeyType, PubKeyText))
-> Maybe (Set (SshKeyType, PubKeyText))
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup User
u (Map User (Set (SshKeyType, PubKeyText))
 -> Maybe (Set (SshKeyType, PubKeyText)))
-> (UserKeyInfo -> Map User (Set (SshKeyType, PubKeyText)))
-> UserKeyInfo
-> Maybe (Set (SshKeyType, PubKeyText))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserKeyInfo -> Map User (Set (SshKeyType, PubKeyText))
fromUserKeyInfo (UserKeyInfo -> [(SshKeyType, PubKeyText)])
-> Propellor UserKeyInfo -> Propellor [(SshKeyType, PubKeyText)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Propellor UserKeyInfo
forall v. IsInfo v => Propellor v
askInfo

newtype UserKeyInfo = UserKeyInfo
	{ UserKeyInfo -> Map User (Set (SshKeyType, PubKeyText))
fromUserKeyInfo :: M.Map User (S.Set (SshKeyType, PubKeyText)) }
	deriving (UserKeyInfo -> UserKeyInfo -> Bool
(UserKeyInfo -> UserKeyInfo -> Bool)
-> (UserKeyInfo -> UserKeyInfo -> Bool) -> Eq UserKeyInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UserKeyInfo -> UserKeyInfo -> Bool
== :: UserKeyInfo -> UserKeyInfo -> Bool
$c/= :: UserKeyInfo -> UserKeyInfo -> Bool
/= :: UserKeyInfo -> UserKeyInfo -> Bool
Eq, Eq UserKeyInfo
Eq UserKeyInfo
-> (UserKeyInfo -> UserKeyInfo -> Ordering)
-> (UserKeyInfo -> UserKeyInfo -> Bool)
-> (UserKeyInfo -> UserKeyInfo -> Bool)
-> (UserKeyInfo -> UserKeyInfo -> Bool)
-> (UserKeyInfo -> UserKeyInfo -> Bool)
-> (UserKeyInfo -> UserKeyInfo -> UserKeyInfo)
-> (UserKeyInfo -> UserKeyInfo -> UserKeyInfo)
-> Ord UserKeyInfo
UserKeyInfo -> UserKeyInfo -> Bool
UserKeyInfo -> UserKeyInfo -> Ordering
UserKeyInfo -> UserKeyInfo -> UserKeyInfo
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UserKeyInfo -> UserKeyInfo -> Ordering
compare :: UserKeyInfo -> UserKeyInfo -> Ordering
$c< :: UserKeyInfo -> UserKeyInfo -> Bool
< :: UserKeyInfo -> UserKeyInfo -> Bool
$c<= :: UserKeyInfo -> UserKeyInfo -> Bool
<= :: UserKeyInfo -> UserKeyInfo -> Bool
$c> :: UserKeyInfo -> UserKeyInfo -> Bool
> :: UserKeyInfo -> UserKeyInfo -> Bool
$c>= :: UserKeyInfo -> UserKeyInfo -> Bool
>= :: UserKeyInfo -> UserKeyInfo -> Bool
$cmax :: UserKeyInfo -> UserKeyInfo -> UserKeyInfo
max :: UserKeyInfo -> UserKeyInfo -> UserKeyInfo
$cmin :: UserKeyInfo -> UserKeyInfo -> UserKeyInfo
min :: UserKeyInfo -> UserKeyInfo -> UserKeyInfo
Ord, Typeable, Int -> UserKeyInfo -> PubKeyText -> PubKeyText
[UserKeyInfo] -> PubKeyText -> PubKeyText
UserKeyInfo -> PubKeyText
(Int -> UserKeyInfo -> PubKeyText -> PubKeyText)
-> (UserKeyInfo -> PubKeyText)
-> ([UserKeyInfo] -> PubKeyText -> PubKeyText)
-> Show UserKeyInfo
forall a.
(Int -> a -> PubKeyText -> PubKeyText)
-> (a -> PubKeyText) -> ([a] -> PubKeyText -> PubKeyText) -> Show a
$cshowsPrec :: Int -> UserKeyInfo -> PubKeyText -> PubKeyText
showsPrec :: Int -> UserKeyInfo -> PubKeyText -> PubKeyText
$cshow :: UserKeyInfo -> PubKeyText
show :: UserKeyInfo -> PubKeyText
$cshowList :: [UserKeyInfo] -> PubKeyText -> PubKeyText
showList :: [UserKeyInfo] -> PubKeyText -> PubKeyText
Show)

instance IsInfo UserKeyInfo where
	propagateInfo :: UserKeyInfo -> PropagateInfo
propagateInfo UserKeyInfo
_ = Bool -> PropagateInfo
PropagateInfo Bool
False

instance Sem.Semigroup UserKeyInfo where
	UserKeyInfo Map User (Set (SshKeyType, PubKeyText))
old <> :: UserKeyInfo -> UserKeyInfo -> UserKeyInfo
<> UserKeyInfo Map User (Set (SshKeyType, PubKeyText))
new =
		Map User (Set (SshKeyType, PubKeyText)) -> UserKeyInfo
UserKeyInfo ((Set (SshKeyType, PubKeyText)
 -> Set (SshKeyType, PubKeyText) -> Set (SshKeyType, PubKeyText))
-> Map User (Set (SshKeyType, PubKeyText))
-> Map User (Set (SshKeyType, PubKeyText))
-> Map User (Set (SshKeyType, PubKeyText))
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
M.unionWith Set (SshKeyType, PubKeyText)
-> Set (SshKeyType, PubKeyText) -> Set (SshKeyType, PubKeyText)
forall a. Ord a => Set a -> Set a -> Set a
S.union Map User (Set (SshKeyType, PubKeyText))
old Map User (Set (SshKeyType, PubKeyText))
new)

instance Monoid UserKeyInfo where
	mempty :: UserKeyInfo
mempty = Map User (Set (SshKeyType, PubKeyText)) -> UserKeyInfo
UserKeyInfo Map User (Set (SshKeyType, PubKeyText))
forall k a. Map k a
M.empty
	mappend :: UserKeyInfo -> UserKeyInfo -> UserKeyInfo
mappend = UserKeyInfo -> UserKeyInfo -> UserKeyInfo
forall a. Semigroup a => a -> a -> a
(Sem.<>)

-- | Sets up a user with the specified public keys, and the corresponding
-- private keys from the privdata.
--
-- The public keys are added to the Info, so other properties like
-- `authorizedKeysFrom` can use them.
userKeys :: IsContext c => User -> c -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + UnixLike)
userKeys :: forall c.
IsContext c =>
User
-> c
-> [(SshKeyType, PubKeyText)]
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
userKeys user :: User
user@(User PubKeyText
name) c
context [(SshKeyType, PubKeyText)]
ks = PubKeyText
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (MetaTypes
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ [Property
   (MetaTypes
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
[Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes)
toProps ([Property
    (MetaTypes
       '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
 -> Props
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
	User
-> [(SshKeyType, PubKeyText)]
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
userPubKeys User
user [(SshKeyType, PubKeyText)]
ks Property
  (MetaTypes
     '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
forall a. a -> [a] -> [a]
: ((SshKeyType, PubKeyText)
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> [(SshKeyType, PubKeyText)]
-> [Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe PubKeyText
-> User
-> c
-> (SshKeyType, PubKeyText)
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall c.
IsContext c =>
Maybe PubKeyText
-> User
-> c
-> (SshKeyType, PubKeyText)
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
userKeyAt Maybe PubKeyText
forall a. Maybe a
Nothing User
user c
context) [(SshKeyType, PubKeyText)]
ks
  where
	desc :: PubKeyText
desc = [PubKeyText] -> PubKeyText
unwords
		[ PubKeyText
name
		, PubKeyText
"has ssh key"
		, PubKeyText
"(" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ [PubKeyText] -> PubKeyText
unwords (((SshKeyType, PubKeyText) -> PubKeyText)
-> [(SshKeyType, PubKeyText)] -> [PubKeyText]
forall a b. (a -> b) -> [a] -> [b]
map (SshKeyType -> PubKeyText
fromKeyType (SshKeyType -> PubKeyText)
-> ((SshKeyType, PubKeyText) -> SshKeyType)
-> (SshKeyType, PubKeyText)
-> PubKeyText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SshKeyType, PubKeyText) -> SshKeyType
forall a b. (a, b) -> a
fst) [(SshKeyType, PubKeyText)]
ks) PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
")"
		]

-- | Sets up a user with the specified pubic key, and a private
-- key from the privdata.
--
-- A FilePath can be specified to write the key to somewhere other than
-- the default locations. Allows a user to have multiple keys for
-- different roles.
--
-- When the FilePath is relative, is put inside the User's 
-- ~/.ssh/ directory.
userKeyAt :: IsContext c => Maybe FilePath -> User -> c -> (SshKeyType, PubKeyText) -> Property (HasInfo + UnixLike)
userKeyAt :: forall c.
IsContext c =>
Maybe PubKeyText
-> User
-> c
-> (SshKeyType, PubKeyText)
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
userKeyAt Maybe PubKeyText
dest user :: User
user@(User PubKeyText
u) c
context (SshKeyType
keytype, PubKeyText
pubkeytext) =
	PubKeyText
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (MetaTypes
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Props
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
props
		Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
pubkey
		Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (Sing
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property
  (MetaTypes
     '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
Property
  (HasInfo
   + MetaTypes
       '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
privkey
  where
	desc :: PubKeyText
desc = [PubKeyText] -> PubKeyText
unwords ([PubKeyText] -> PubKeyText) -> [PubKeyText] -> PubKeyText
forall a b. (a -> b) -> a -> b
$ [Maybe PubKeyText] -> [PubKeyText]
forall a. [Maybe a] -> [a]
catMaybes
		[ PubKeyText -> Maybe PubKeyText
forall a. a -> Maybe a
Just PubKeyText
u
		, PubKeyText -> Maybe PubKeyText
forall a. a -> Maybe a
Just PubKeyText
"has ssh key"
		, Maybe PubKeyText
dest
		, PubKeyText -> Maybe PubKeyText
forall a. a -> Maybe a
Just (PubKeyText -> Maybe PubKeyText) -> PubKeyText -> Maybe PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText
"(" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ SshKeyType -> PubKeyText
fromKeyType SshKeyType
keytype PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
")"
		]
	pubkey :: Property UnixLike
	pubkey :: Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
pubkey = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc ((OuterMetaTypesWitness
    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> 
		OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      (Combine
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Propellor Result)
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
-> Propellor Result
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (PubKeyText
 -> [PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> PubKeyText
-> [PubKeyText]
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
installprop PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.hasContent PubKeyText
".pub" [PubKeyText
pubkeytext]
	privkey :: Property (HasInfo + UnixLike)
	privkey :: Property
  (HasInfo
   + MetaTypes
       '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
privkey = PrivDataField
-> c
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property
         (MetaTypes
            '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall c s metatypes.
(IsContext c, IsPrivDataSource s,
 IncludesInfo metatypes ~ 'True) =>
s
-> c
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property metatypes)
-> Property metatypes
withPrivData (SshKeyType -> PubKeyText -> PrivDataField
SshPrivKey SshKeyType
keytype PubKeyText
u) c
context ((PrivData -> Propellor Result) -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
((PrivData -> Propellor Result) -> Propellor Result)
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
privkey'
	privkey' :: ((PrivData -> Propellor Result) -> Propellor Result) -> Property (HasInfo + UnixLike)
	privkey' :: ((PrivData -> Propellor Result) -> Propellor Result)
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
privkey' (PrivData -> Propellor Result) -> Propellor Result
getkey = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc ((OuterMetaTypesWitness
    '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> (PrivData -> Propellor Result) -> Propellor Result
getkey ((PrivData -> Propellor Result) -> Propellor Result)
-> (PrivData -> Propellor Result) -> Propellor Result
forall a b. (a -> b) -> a -> b
$ \PrivData
k ->
		OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w
			(Property
   (MetaTypes
      (Combine
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Propellor Result)
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
-> Propellor Result
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (PubKeyText
 -> [PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> PubKeyText
-> [PubKeyText]
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
installprop PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.hasContentProtected PubKeyText
"" (PrivData -> [PubKeyText]
privDataLines PrivData
k)
	installprop :: (PubKeyText
 -> [PubKeyText]
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> PubKeyText
-> [PubKeyText]
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
installprop PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
writer PubKeyText
ext [PubKeyText]
key = do
		PubKeyText
f <- IO PubKeyText -> Propellor PubKeyText
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PubKeyText -> Propellor PubKeyText)
-> IO PubKeyText -> Propellor PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText -> IO PubKeyText
keyfile PubKeyText
ext
		Property
  (MetaTypes
     (Combine
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return (Property
   (MetaTypes
      (Combine
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Propellor
      (Property
         (MetaTypes
            (Combine
               (Combine
                  (Combine
                     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))))
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Propellor
     (Property
        (MetaTypes
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
forall a b. (a -> b) -> a -> b
$ PubKeyText
-> Props
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (MetaTypes
      (Combine
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Property
      (MetaTypes
         (Combine
            (Combine
               (Combine
                  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
-> Props
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall a b. (a -> b) -> a -> b
$ Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
props
			Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.dirExists (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f)
			Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
writer PubKeyText
f ([PubKeyText] -> [PubKeyText]
keyFileContent [PubKeyText]
key)
			Props
  (MetaTypes
     (Combine
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup PubKeyText
f User
user (User -> Group
userGroup User
user)
			Props
  (Sing
     (Combine
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f) User
user (User -> Group
userGroup User
user)
	keyfile :: PubKeyText -> IO PubKeyText
keyfile PubKeyText
ext = case Maybe PubKeyText
dest of
		Maybe PubKeyText
Nothing -> PubKeyText -> IO PubKeyText
relhomessh (PubKeyText -> IO PubKeyText) -> PubKeyText -> IO PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText
"id_" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ SshKeyType -> PubKeyText
fromKeyType SshKeyType
keytype PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
ext
		Just PubKeyText
f
			| PubKeyText -> Bool
isRelative PubKeyText
f -> PubKeyText -> IO PubKeyText
relhomessh (PubKeyText
f PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
ext)
			| Bool
otherwise -> PubKeyText -> IO PubKeyText
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKeyText
f PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
ext)
	relhomessh :: PubKeyText -> IO PubKeyText
relhomessh PubKeyText
f = do
		PubKeyText
home <- UserEntry -> PubKeyText
homeDirectory (UserEntry -> PubKeyText) -> IO UserEntry -> IO PubKeyText
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PubKeyText -> IO UserEntry
getUserEntryForName PubKeyText
u
		PubKeyText -> IO PubKeyText
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKeyText -> IO PubKeyText) -> PubKeyText -> IO PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText
home PubKeyText -> PubKeyText -> PubKeyText
</> PubKeyText
".ssh" PubKeyText -> PubKeyText -> PubKeyText
</> PubKeyText
f

fromKeyType :: SshKeyType -> String
fromKeyType :: SshKeyType -> PubKeyText
fromKeyType SshKeyType
SshRsa = PubKeyText
"rsa"
fromKeyType SshKeyType
SshDsa = PubKeyText
"dsa"
fromKeyType SshKeyType
SshEcdsa = PubKeyText
"ecdsa"
fromKeyType SshKeyType
SshEd25519 = PubKeyText
"ed25519"

-- | Puts some host's ssh public key(s), as set using `hostPubKey`
-- or `hostKey` into the known_hosts file for a user.
knownHost :: [Host] -> HostName -> User -> Property UnixLike
knownHost :: [Host]
-> PubKeyText
-> User
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
knownHost [Host]
hosts PubKeyText
hn user :: User
user@(User PubKeyText
u) = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc ((OuterMetaTypesWitness
    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w ->
	OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w ([PubKeyText] -> Propellor Result)
-> Propellor [PubKeyText] -> Propellor Result
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Host] -> PubKeyText -> Propellor [PubKeyText]
knownHostLines [Host]
hosts PubKeyText
hn
  where
	desc :: PubKeyText
desc = PubKeyText
u PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" knows ssh key for " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
hn

	go :: OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
_ [] = do
		PubKeyText -> Propellor ()
forall (m :: * -> *). MonadIO m => PubKeyText -> m ()
warningMessage (PubKeyText -> Propellor ()) -> PubKeyText -> Propellor ()
forall a b. (a -> b) -> a -> b
$ PubKeyText
"no configured ssh host keys for " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
hn
		Result -> Propellor Result
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return Result
FailedChange
	go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w [PubKeyText]
ls = do
		PubKeyText
f <- IO PubKeyText -> Propellor PubKeyText
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PubKeyText -> Propellor PubKeyText)
-> IO PubKeyText -> Propellor PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
"known_hosts" User
user
		OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ User
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
modKnownHost User
user PubKeyText
f (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
			PubKeyText
f PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`File.containsLines` [PubKeyText]
ls
				Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`requires` PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.dirExists (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f)

-- | Reverts `knownHost`
unknownHost :: [Host] -> HostName -> User -> Property UnixLike
unknownHost :: [Host]
-> PubKeyText
-> User
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
unknownHost [Host]
hosts PubKeyText
hn user :: User
user@(User PubKeyText
u) = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc ((OuterMetaTypesWitness
    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w ->
	OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w ([PubKeyText] -> Propellor Result)
-> Propellor [PubKeyText] -> Propellor Result
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Host] -> PubKeyText -> Propellor [PubKeyText]
knownHostLines [Host]
hosts PubKeyText
hn
  where
	desc :: PubKeyText
desc = PubKeyText
u PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" does not know ssh key for " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
hn

	go :: OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
_ [] = Result -> Propellor Result
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return Result
NoChange
	go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w [PubKeyText]
ls = do
		PubKeyText
f <- IO PubKeyText -> Propellor PubKeyText
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PubKeyText -> Propellor PubKeyText)
-> IO PubKeyText -> Propellor PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
"known_hosts" User
user
		Propellor Bool
-> (Propellor Result, Propellor Result) -> Propellor Result
forall (m :: * -> *) a. Monad m => m Bool -> (m a, m a) -> m a
ifM (IO Bool -> Propellor Bool
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> Propellor Bool) -> IO Bool -> Propellor Bool
forall a b. (a -> b) -> a -> b
$ PubKeyText -> IO Bool
doesFileExist PubKeyText
f)
			( OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ User
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
modKnownHost User
user PubKeyText
f (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
				PubKeyText
f PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`File.lacksLines` [PubKeyText]
ls
			, Result -> Propellor Result
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return Result
NoChange
			)

knownHostLines :: [Host] -> HostName -> Propellor [File.Line]
knownHostLines :: [Host] -> PubKeyText -> Propellor [PubKeyText]
knownHostLines [Host]
hosts PubKeyText
hn = Maybe (Map SshKeyType PubKeyText) -> [PubKeyText]
keylines (Maybe (Map SshKeyType PubKeyText) -> [PubKeyText])
-> Propellor (Maybe (Map SshKeyType PubKeyText))
-> Propellor [PubKeyText]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Host]
-> PubKeyText
-> Propellor (Map SshKeyType PubKeyText)
-> Propellor (Maybe (Map SshKeyType PubKeyText))
forall a.
[Host] -> PubKeyText -> Propellor a -> Propellor (Maybe a)
fromHost [Host]
hosts PubKeyText
hn Propellor (Map SshKeyType PubKeyText)
getHostPubKey
  where
	keylines :: Maybe (Map SshKeyType PubKeyText) -> [PubKeyText]
keylines (Just Map SshKeyType PubKeyText
m) = (PubKeyText -> PubKeyText) -> [PubKeyText] -> [PubKeyText]
forall a b. (a -> b) -> [a] -> [b]
map (\PubKeyText
k -> PubKeyText
hn PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
k) (Map SshKeyType PubKeyText -> [PubKeyText]
forall k a. Map k a -> [a]
M.elems Map SshKeyType PubKeyText
m)
	keylines Maybe (Map SshKeyType PubKeyText)
Nothing = []

modKnownHost :: User -> FilePath -> Property UnixLike -> Property UnixLike
modKnownHost :: User
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
modKnownHost User
user PubKeyText
f Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
p = Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
p
	Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`before` PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup PubKeyText
f User
user (User -> Group
userGroup User
user)
	Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`before` PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f) User
user (User -> Group
userGroup User
user)

-- | Ensures that a local user's authorized_keys contains lines allowing
-- logins from a remote user on the specified Host.
--
-- The ssh keys of the remote user can be set using `userKeys`
--
-- Any other lines in the authorized_keys file are preserved as-is.
authorizedKeysFrom :: User -> (User, Host) -> Property UnixLike
localuser :: User
localuser@(User PubKeyText
ln) authorizedKeysFrom :: User
-> (User, Host)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`authorizedKeysFrom` (remoteuser :: User
remoteuser@(User PubKeyText
rn), Host
remotehost) =
	PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc (\OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w ([PubKeyText] -> Propellor Result)
-> Propellor [PubKeyText] -> Propellor Result
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< User -> Host -> Propellor [PubKeyText]
authorizedKeyLines User
remoteuser Host
remotehost)
  where
	remote :: PubKeyText
remote = PubKeyText
rn PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
"@" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ Host -> PubKeyText
hostName Host
remotehost
	desc :: PubKeyText
desc = PubKeyText
ln PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" authorized_keys from " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
remote

	go :: OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
_ [] = do
		PubKeyText -> Propellor ()
forall (m :: * -> *). MonadIO m => PubKeyText -> m ()
warningMessage (PubKeyText -> Propellor ()) -> PubKeyText -> Propellor ()
forall a b. (a -> b) -> a -> b
$ PubKeyText
"no configured ssh user keys for " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
remote
		Result -> Propellor Result
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return Result
FailedChange
	go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w [PubKeyText]
ls = OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ PubKeyText
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ [Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
[Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes)
toProps ([Property
    (MetaTypes
       '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
 -> Props
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> [Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
		(PubKeyText
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> [PubKeyText]
-> [Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
forall a b. (a -> b) -> [a] -> [b]
map (RevertableProperty
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall setupmetatypes undometatypes.
RevertableProperty setupmetatypes undometatypes
-> Property setupmetatypes
setupRevertableProperty (RevertableProperty
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (PubKeyText
    -> RevertableProperty
         (MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         (MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. User
-> PubKeyText
-> RevertableProperty
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
authorizedKey User
localuser) [PubKeyText]
ls

-- | Reverts `authorizedKeysFrom`
unauthorizedKeysFrom :: User -> (User, Host) -> Property UnixLike
localuser :: User
localuser@(User PubKeyText
ln) unauthorizedKeysFrom :: User
-> (User, Host)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`unauthorizedKeysFrom` (remoteuser :: User
remoteuser@(User PubKeyText
rn), Host
remotehost) =
	PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc (\OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w ([PubKeyText] -> Propellor Result)
-> Propellor [PubKeyText] -> Propellor Result
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< User -> Host -> Propellor [PubKeyText]
authorizedKeyLines User
remoteuser Host
remotehost)
  where
	remote :: PubKeyText
remote = PubKeyText
rn PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
"@" PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ Host -> PubKeyText
hostName Host
remotehost
	desc :: PubKeyText
desc = PubKeyText
ln PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" unauthorized_keys from " PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
remote

	go :: OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> [PubKeyText] -> Propellor Result
go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
_ [] = Result -> Propellor Result
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return Result
NoChange
	go OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w [PubKeyText]
ls = OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ PubKeyText
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ [Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
[Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes)
toProps ([Property
    (MetaTypes
       '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
          'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
 -> Props
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> [Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
-> Props
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
		(PubKeyText
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> [PubKeyText]
-> [Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])]
forall a b. (a -> b) -> [a] -> [b]
map (RevertableProperty
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall setupmetatypes undometatypes.
RevertableProperty setupmetatypes undometatypes
-> Property undometatypes
undoRevertableProperty (RevertableProperty
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (PubKeyText
    -> RevertableProperty
         (MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         (MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. User
-> PubKeyText
-> RevertableProperty
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
authorizedKey User
localuser) [PubKeyText]
ls

authorizedKeyLines :: User -> Host -> Propellor [File.Line]
authorizedKeyLines :: User -> Host -> Propellor [PubKeyText]
authorizedKeyLines User
remoteuser Host
remotehost =
	((SshKeyType, PubKeyText) -> PubKeyText)
-> [(SshKeyType, PubKeyText)] -> [PubKeyText]
forall a b. (a -> b) -> [a] -> [b]
map (SshKeyType, PubKeyText) -> PubKeyText
forall a b. (a, b) -> b
snd ([(SshKeyType, PubKeyText)] -> [PubKeyText])
-> Propellor [(SshKeyType, PubKeyText)] -> Propellor [PubKeyText]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Host
-> Propellor [(SshKeyType, PubKeyText)]
-> Propellor [(SshKeyType, PubKeyText)]
forall a. Host -> Propellor a -> Propellor a
fromHost' Host
remotehost (User -> Propellor [(SshKeyType, PubKeyText)]
getUserPubKeys User
remoteuser)

-- | Makes a user have authorized_keys from the PrivData
--
-- This removes any other lines from the file.
authorizedKeys :: IsContext c => User -> c -> Property (HasInfo + UnixLike)
authorizedKeys :: forall c.
IsContext c =>
User
-> c
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
authorizedKeys user :: User
user@(User PubKeyText
u) c
context = PrivDataField
-> c
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property
         (HasInfo
          + MetaTypes
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall c s metatypes.
(IsContext c, IsPrivDataSource s,
 IncludesInfo metatypes ~ 'True) =>
s
-> c
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property metatypes)
-> Property metatypes
withPrivData (PubKeyText -> PrivDataField
SshAuthorizedKeys PubKeyText
u) c
context ((((PrivData -> Propellor Result) -> Propellor Result)
  -> Property
       (HasInfo
        + MetaTypes
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Property
      (HasInfo
       + MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (((PrivData -> Propellor Result) -> Propellor Result)
    -> Property
         (HasInfo
          + MetaTypes
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (HasInfo
      + MetaTypes
          '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
             'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \(PrivData -> Propellor Result) -> Propellor Result
get ->
	PubKeyText
-> (OuterMetaTypesWitness
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' PubKeyText
desc ((OuterMetaTypesWitness
    '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> (PrivData -> Propellor Result) -> Propellor Result
get ((PrivData -> Propellor Result) -> Propellor Result)
-> (PrivData -> Propellor Result) -> Propellor Result
forall a b. (a -> b) -> a -> b
$ \PrivData
v -> do
		PubKeyText
f <- IO PubKeyText -> Propellor PubKeyText
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PubKeyText -> Propellor PubKeyText)
-> IO PubKeyText -> Propellor PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
"authorized_keys" User
user
		OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (Sing
      (Combine
         (Combine
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Propellor Result)
-> Property
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ PubKeyText
-> Props
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties PubKeyText
desc (Props
   (Sing
      (Combine
         (Combine
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
 -> Property
      (Sing
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
-> Props
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall a b. (a -> b) -> a -> b
$ Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
props
			Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> [PubKeyText]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.hasContentProtected PubKeyText
f ([PubKeyText] -> [PubKeyText]
keyFileContent (PrivData -> [PubKeyText]
privDataLines PrivData
v))
			Props
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (MetaTypes
        (Combine
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup PubKeyText
f User
user (User -> Group
userGroup User
user)
			Props
  (MetaTypes
     (Combine
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Props
     (Sing
        (Combine
           (Combine
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f) User
user (User -> Group
userGroup User
user)
  where
	desc :: PubKeyText
desc = PubKeyText
u PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" has authorized_keys"

-- | Ensures that a user's authorized_keys contains a line.
-- Any other lines in the file are preserved as-is.
authorizedKey :: User -> String -> RevertableProperty UnixLike UnixLike
authorizedKey :: User
-> PubKeyText
-> RevertableProperty
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
authorizedKey user :: User
user@(User PubKeyText
u) PubKeyText
l = Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
add Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> RevertableProperty
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall setupmetatypes undometatypes.
Property setupmetatypes
-> Property undometatypes
-> RevertableProperty setupmetatypes undometatypes
<!> Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
remove
  where
	add :: Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
add = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' (PubKeyText
u PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" has authorized_keys") ((OuterMetaTypesWitness
    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> do
		PubKeyText
f <- IO PubKeyText -> Propellor PubKeyText
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PubKeyText -> Propellor PubKeyText)
-> IO PubKeyText -> Propellor PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
"authorized_keys" User
user
		OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ PubKeyText
-> User
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
modAuthorizedKey PubKeyText
f User
user (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
			PubKeyText
f PubKeyText
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`File.containsLine` PubKeyText
l
				Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`requires` PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.dirExists (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f)
	remove :: Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
remove = PubKeyText
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall {k} (metatypes :: k).
SingI metatypes =>
PubKeyText
-> (OuterMetaTypesWitness metatypes -> Propellor Result)
-> Property (MetaTypes metatypes)
property' (PubKeyText
u PubKeyText -> PubKeyText -> PubKeyText
forall a. [a] -> [a] -> [a]
++ PubKeyText
" lacks authorized_keys") ((OuterMetaTypesWitness
    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
       'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
  -> Propellor Result)
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> (OuterMetaTypesWitness
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
    -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$ \OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w -> do
		PubKeyText
f <- IO PubKeyText -> Propellor PubKeyText
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PubKeyText -> Propellor PubKeyText)
-> IO PubKeyText -> Propellor PubKeyText
forall a b. (a -> b) -> a -> b
$ PubKeyText -> User -> IO PubKeyText
dotFile PubKeyText
"authorized_keys" User
user
		Propellor Bool
-> (Propellor Result, Propellor Result) -> Propellor Result
forall (m :: * -> *) a. Monad m => m Bool -> (m a, m a) -> m a
ifM (IO Bool -> Propellor Bool
forall a. IO a -> Propellor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> Propellor Bool) -> IO Bool -> Propellor Bool
forall a b. (a -> b) -> a -> b
$ PubKeyText -> IO Bool
doesFileExist PubKeyText
f)
			( OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall (inner :: [MetaType]) (outer :: [MetaType]).
EnsurePropertyAllowed inner outer =>
OuterMetaTypesWitness outer
-> Property (MetaTypes inner) -> Propellor Result
ensureProperty OuterMetaTypesWitness
  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
     'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
w (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Propellor Result)
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Propellor Result
forall a b. (a -> b) -> a -> b
$ PubKeyText
-> User
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
modAuthorizedKey PubKeyText
f User
user (Property
   (MetaTypes
      '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
         'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
 -> Property
      (MetaTypes
         '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
            'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
forall a b. (a -> b) -> a -> b
$
				PubKeyText
f PubKeyText
-> PubKeyText
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
`File.lacksLine` PubKeyText
l
			, Result -> Propellor Result
forall a. a -> Propellor a
forall (m :: * -> *) a. Monad m => a -> m a
return Result
NoChange
			)

modAuthorizedKey :: FilePath -> User -> Property UnixLike -> Property UnixLike
modAuthorizedKey :: PubKeyText
-> User
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
modAuthorizedKey PubKeyText
f User
user Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
p = Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
p
	Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`before` PubKeyText
-> FileMode
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.mode PubKeyText
f ([FileMode] -> FileMode
combineModes [FileMode
ownerWriteMode, FileMode
ownerReadMode])
	Property
  (MetaTypes
     '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
        'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`before` PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup PubKeyText
f User
user (User -> Group
userGroup User
user)
	CombinedType
  (Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
  (Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
-> CombinedType
     (CombinedType
        (Property
           (MetaTypes
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
        (Property
           (MetaTypes
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])))
     (Property
        (MetaTypes
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
forall x y. Combines x y => x -> y -> CombinedType x y
`before` PubKeyText
-> User
-> Group
-> Property
     (MetaTypes
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
           'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
File.ownerGroup (PubKeyText -> PubKeyText
takeDirectory PubKeyText
f) User
user (User -> Group
userGroup User
user)