packages feed

openssh-github-keys (empty) → 0.1.0.0

raw patch · 6 files changed

+217/−0 lines, 6 filesdep +basedep +directorydep +dotenvsetup-changed

Dependencies added: base, directory, dotenv, filepath, hspec, octohat, optparse-applicative, text, unix

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Justin Leitgeb++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ openssh-github-keys.cabal view
@@ -0,0 +1,70 @@+name:                openssh-github-keys+version:             0.1.0.0+synopsis:            Fetch OpenSSH keys from a Github team+description:+  .+  This package fetches the OpenSSH public keys for all users from a+  Github team. It is intended to be executed from the AuthorizedKeys+  command in the sshd_config file, which then allows users to log in+  using keys that they have in their Github accounts.+  .+homepage:            https://github.com/stackbuilders/openssh-github-keys+license:             MIT+license-file:        LICENSE+author:              Stack Builders+maintainer:          hackage@stackbuilders.com+copyright:           2015 Stack Builders Inc.+category:            System+build-type:          Simple+-- extra-source-files:+cabal-version:       >=1.10++Homepage:            https://github.com/stackbuilders/openssh-github-keys+Bug-reports:         https://github.com/stackbuilders/openssh-github-keys/issues++executable openssh-github-keys+  main-is:             Main.hs+  -- other-modules:+  -- other-extensions:+  build-depends:       base >=4.5 && <4.8+                       , octohat >=0.1.2+                       , dotenv+                       , text+                       , optparse-applicative+                       , directory+                       , filepath+                       , unix++  hs-source-dirs:      src+  ghc-options:         -Wall++  default-language:    Haskell2010++library+  exposed-modules:    System.OpensshGithubKeys++  build-depends:         base >=4.5 && <4.8+                       , octohat >=0.1.2+                       , text++  hs-source-dirs:      src+  default-language:    Haskell2010+  ghc-options:         -Wall+++test-suite openssh-github-keys-test+  type: exitcode-stdio-1.0+  hs-source-dirs: spec, src+  main-is: Spec.hs+  build-depends:       base >=4.5 && <4.8+                       , octohat >=0.1.2+                       , text++                       , hspec++  default-language:    Haskell2010+  ghc-options:         -Wall++source-repository head+  type: git+  location: https://github.com/stackbuilders/openssh-github-keys
+ spec/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ src/Main.hs view
@@ -0,0 +1,108 @@+{-# LANGUAGE OverloadedStrings #-}++module Main where++import Options.Applicative++import qualified Data.Text as T++import Network.Octohat (keysOfTeamInOrganization)+import Network.Octohat.Types (runGitHub, OrganizationName(..),+                              TeamName(..))++import System.OpensshGithubKeys (formatKey)++import System.Timeout (timeout)++import qualified Configuration.Dotenv as Dotenv++data Options = Options+  { localUser    :: String+  , organization :: String+  , team         :: String+  , users        :: [String]+  , dotfile      :: Maybe FilePath++  } deriving (Show)+++fetchKeys :: Options -> IO ()+fetchKeys opts = do+  if any (\u -> localUser opts == u) (users opts)+    then do+      res <- runGitHub $ keysOfTeamInOrganization+             (OrganizationName $ T.pack $ organization opts)+             (TeamName $ T.pack $ team opts)++      case res of+        Right membersWithKeys ->+          putStrLn $ unlines $ concatMap formatKey membersWithKeys++        Left e -> error $ "Error retrieving keys for organization '" ++ show e++    else return ()++config :: Parser Options+config = Options+     <$> argument str (metavar "AUTHENTICATE"+                       <> help "Local user trying to authenticate currently")++     <*> strOption (+             long "organization"+             <> short 'o'+             <> metavar "ORGANIZATION"+             <> help "GitHub organization from which to select teams")++     <*> strOption (+                  long "team"+                  <> short 't'+                  <> metavar "TEAM"+                  <> help "GitHub team from which to select members' keys" )++     <*> some (strOption (+                  long "user"+                  <> short 'u'+                  <> metavar "USER"+                  <> help "A local user that we should try to authenticate using Github" ))++     <*> strOptional (+                  long "dotfile"+                  <> short 'f'+                  <> metavar "DOTFILE"+                  <> help "File in 'dotfile' format specifying GITHUB_TOKEN" )++strOptional :: Mod OptionFields String -> Parser (Maybe String)+strOptional flags = Just <$> strOption flags <|> pure Nothing++main :: IO ()+main = do+  options <- execParser opts+  readDotenvFile options++  res <- timeout allowedTime (fetchKeys options)+  case res of+    Nothing -> error $ "Allowed time of " ++ show allowedTime +++               " microseconds exceeded while fetching keys from GitHub."+    Just  _ -> return ()++  where+    allowedTime = 5 * 1000000 -- Allowed time in microseconds for fetching keys+    opts = info (helper <*> config)+      ( fullDesc++     <> progDesc (unlines+        [ "Fetches ssh public keys from TEAMS under ORGANIZATION on GitHub."+        , "The output format is suitable for AuthorizedKeysCommand in"+        , "sshd_config. Requires a github token, which can be specified"+        , "in an environment variable GITHUB_TOKEN or in a dotenv file which"+        , "can be specified with the -f option."])++     <> header "openssh-github-keys - fetches team member keys from GitHub"+      )++-- | Conditionally reads the ~/.github_token file if it exists.+readDotenvFile :: Options -> IO ()+readDotenvFile opts =+  case dotfile opts of+    Just f -> Dotenv.loadFile False f+    Nothing -> return ()
+ src/System/OpensshGithubKeys.hs view
@@ -0,0 +1,16 @@+module System.OpensshGithubKeys (formatKey) where++import Data.List (intercalate)++import qualified Data.Text as T++import Network.Octohat.Types (Member(..), MemberWithKey(..), PublicKey(..))++-- | Returns a list of keys for the user, with the username appended for easier+-- identification.+formatKey :: MemberWithKey -> [String]+formatKey mkeys =+  map (\k -> intercalate " " [(T.unpack $ publicKey k), ghUsername])+  (memberKey mkeys)++  where ghUsername = (T.unpack . memberLogin . member) mkeys