;;; aws.el --- Some shortcuts for working with AWS -*- lexical-binding: t -*- ;; This file is not part of GNU Emacs ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; commentary ;;; Code: (defcustom aws-cli-auth-provider "saml2aws" "The command that provides AWS authentication." :type 'string :group 'aws :group 'theurgy) (defcustom aws-roles '() "List of strings of each possible AWS role completion for `aws-sign-in'." :type '(repeat string) :group 'aws :group 'theurgy) (defcustom aws-auto-reauth nil "If nil, do not reauth. Otherwise it should be a number, the number of minutes on the reauth timer." :type 'integer :group 'aws :group 'theurgy) (defvar aws-reauth-timer nil "The reauth timer, if created.") (defvar aws-post-signin-hook nil "Hook to run after an AWS sign-in.") (defun aws--login (role) "Internal login function --- handles the command as a process, and prompts for MFA." (let* ((process-name (format "%s-%s" aws-cli-auth-provider (replace-regexp-in-string "[/:]" "-" role))) (buffer (get-buffer-create (format "*%s*" process-name))) (prompt-regexp (rx (or "Enter verification code"))) (prompt-sent nil)) (with-current-buffer buffer (erase-buffer)) (make-process :name process-name :buffer buffer :command (list aws-cli-auth-provider "login" "--force" "--skip-prompt" "--role" role) :filter (lambda (proc output) (with-current-buffer (process-buffer proc) (goto-char (point-max)) (insert output) (unless prompt-sent (let ((buffer-contents (buffer-string))) (when (string-match-p prompt-regexp buffer-contents) (setq prompt-sent t) (let ((token (read-passwd "MFA token: "))) (process-send-string proc (concat token "\n")))))))) :sentinel (lambda (proc event) (when (string= "finished\n" event) (run-hooks 'aws-post-signin-hook)))))) (defun aws-sign-in () "Sign in with AWS." (interactive) (let* ((role (completing-read "AWS Role: " aws-roles)) (auth-fn (lambda () (message (concat "Authenticating with " role " via " aws-cli-auth-provider)) (aws--login role)))) (funcall auth-fn) (when aws-auto-reauth (when aws-reauth-timer (cancel-timer aws-reauth-timer)) (setq aws-reauth-timer (run-at-time 0 (* 60 aws-auto-reauth) auth-fn))))) (provide 'aws) ;;; aws.el ends here