From 6fe687fdf662a7495b20a1d94f27bf557525af58 Mon Sep 17 00:00:00 2001
From: Dean Troyer <dtroyer@gmail.com>
Date: Thu, 12 Sep 2013 14:49:41 -0500
Subject: [PATCH] Delay authentication to handle commands that do not require
 it

* Move the auth to OpenStackShell.prepare_to_run_command() and skip it if
  the command's auth_required == False
* Default auth_required = True for all commands
* Do authentication up-front for interactive use as
  OpenStackShell.prepare_to_run_command() is not called

Change-Id: Id330092f242af624f430d469882d15f4a22f4e37
---
 openstackclient/shell.py | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index 6cb7c1ee2c..6797790708 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -22,6 +22,7 @@ import os
 import sys
 
 from cliff import app
+from cliff import command
 from cliff import help
 
 import openstackclient
@@ -64,6 +65,11 @@ class OpenStackShell(app.App):
     log = logging.getLogger(__name__)
 
     def __init__(self):
+        # Patch command.Command to add a default auth_required = True
+        command.Command.auth_required = True
+        # But not help
+        help.HelpCommand.auth_required = False
+
         super(OpenStackShell, self).__init__(
             description=__doc__.strip(),
             version=openstackclient.__version__,
@@ -383,20 +389,13 @@ class OpenStackShell(app.App):
         # Set up common client session
         self.restapi = restapi.RESTApi()
 
-        # If the user is not asking for help, make sure they
-        # have given us auth.
-        cmd_name = None
-        if argv:
-            cmd_info = self.command_manager.find_command(argv)
-            cmd_factory, cmd_name, sub_argv = cmd_info
-        if self.interactive_mode or cmd_name != 'help':
-            self.authenticate_user()
-            self.restapi.set_auth(self.client_manager.identity.auth_token)
-
     def prepare_to_run_command(self, cmd):
         """Set up auth and API versions"""
         self.log.debug('prepare_to_run_command %s', cmd.__class__.__name__)
-        self.log.debug("api: %s" % cmd.api if hasattr(cmd, 'api') else None)
+
+        if cmd.auth_required:
+            self.authenticate_user()
+            self.restapi.set_auth(self.client_manager.identity.auth_token)
         return
 
     def clean_up(self, cmd, result, err):
@@ -404,6 +403,13 @@ class OpenStackShell(app.App):
         if err:
             self.log.debug('got an error: %s', err)
 
+    def interact(self):
+        # NOTE(dtroyer): Maintain the old behaviour for interactive use as
+        #                this path does not call prepare_to_run_command()
+        self.authenticate_user()
+        self.restapi.set_auth(self.client_manager.identity.auth_token)
+        super(OpenStackShell, self).interact()
+
 
 def main(argv=sys.argv[1:]):
     try: