module Propellor.Git.VerifiedBranch where

import Propellor.Base
import Propellor.Git
import Propellor.PrivData.Paths
import Utility.FileMode

{- To verify origin branch commit's signature, have to convince gpg
 - to use our keyring while running git verify-tag.
 - Which has no way to pass options to gpg. Argh!
 -}
verifyOriginBranch :: String -> IO Bool
verifyOriginBranch originbranch = do
        let gpgconf = privDataDir </> "gpg.conf"
        keyring <- privDataKeyring
        writeFile gpgconf $ unlines
                [ " keyring " ++ keyring
                , "no-auto-check-trustdb"
                ]
        -- gpg is picky about perms
        modifyFileMode privDataDir (removeModes otherGroupModes)
        verified <- boolSystemEnv "git" [Param "verify-commit", Param originbranch]
                (Just [("GNUPGHOME", privDataDir)])
        nukeFile $ privDataDir </> "trustdb.gpg"
        nukeFile $ privDataDir </> "pubring.gpg"
        nukeFile $ privDataDir </> "gpg.conf"
        return verified

-- Returns True if HEAD is changed by fetching and merging from origin.
fetchOrigin :: IO Bool
fetchOrigin = do
        fetched <- actionMessage "Pull from central git repository" $
                boolSystem "git" [Param "fetch"]
        if fetched
                then mergeOrigin
                else return False

mergeOrigin :: IO Bool
mergeOrigin = do
        branchref <- getCurrentBranch
        let originbranch = "origin" </> branchref

        oldsha <- getCurrentGitSha1 branchref

        keyring <- privDataKeyring
        whenM (doesFileExist keyring) $
                ifM (verifyOriginBranch originbranch)
                        ( do
                                putStrLn $ "git branch " ++ originbranch ++ " gpg signature verified; merging"
                                hFlush stdout
                                void $ boolSystem "git" [Param "merge", Param originbranch]
                        , warningMessage $ "git branch " ++ originbranch ++ " is not signed with a trusted gpg key; refusing to deploy it! (Running with previous configuration instead.)"
                        )

        newsha <- getCurrentGitSha1 branchref
        return $ oldsha /= newsha