|
3 | 3 | using Autofac; |
4 | 4 | using CKAN.Configuration; |
5 | 5 | using CommandLine; |
6 | | -using CommandLine.Text; |
7 | | -using log4net; |
8 | 6 |
|
9 | | -namespace CKAN.CmdLine |
| 7 | +namespace CKAN.CmdLine.Action |
10 | 8 | { |
11 | 9 | /// <summary> |
12 | | - /// Subcommand for managing authentication tokens |
| 10 | + /// Class for managing authentication tokens. |
13 | 11 | /// </summary> |
14 | 12 | public class AuthToken : ISubCommand |
15 | 13 | { |
16 | | - /// <summary> |
17 | | - /// Initialize the subcommand |
18 | | - /// </summary> |
19 | | - public AuthToken() { } |
| 14 | + private GameInstanceManager _manager; |
| 15 | + private IUser _user; |
20 | 16 |
|
21 | 17 | /// <summary> |
22 | | - /// Run the subcommand |
| 18 | + /// Run the 'authtoken' command. |
23 | 19 | /// </summary> |
24 | | - /// <param name="mgr">Manager to provide game instances</param> |
25 | | - /// <param name="opts">Command line parameters paritally handled by parser</param> |
26 | | - /// <param name="unparsed">Command line parameters not yet handled by parser</param> |
27 | | - /// <returns> |
28 | | - /// Exit code |
29 | | - /// </returns> |
30 | | - public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCommandOptions unparsed) |
| 20 | + /// <inheritdoc cref="ISubCommand.RunCommand"/> |
| 21 | + public int RunCommand(GameInstanceManager manager, object args) |
31 | 22 | { |
32 | | - string[] args = unparsed.options.ToArray(); |
33 | | - int exitCode = Exit.OK; |
| 23 | + var s = args.ToString(); |
| 24 | + var opts = s.Replace(s.Substring(0, s.LastIndexOf('.') + 1), "").Split('+'); |
| 25 | + |
| 26 | + CommonOptions options = new CommonOptions(); |
| 27 | + _user = new ConsoleUser(options.Headless); |
| 28 | + _manager = manager ?? new GameInstanceManager(_user); |
| 29 | + var exitCode = options.Handle(_manager, _user); |
| 30 | + |
| 31 | + if (exitCode != Exit.Ok) |
| 32 | + return exitCode; |
34 | 33 |
|
35 | | - Parser.Default.ParseArgumentsStrict(args, new AuthTokenSubOptions(), (string option, object suboptions) => |
| 34 | + switch (opts[1]) |
36 | 35 | { |
37 | | - if (!string.IsNullOrEmpty(option) && suboptions != null) |
38 | | - { |
39 | | - CommonOptions options = (CommonOptions)suboptions; |
40 | | - options.Merge(opts); |
41 | | - user = new ConsoleUser(options.Headless); |
42 | | - if (manager == null) |
43 | | - { |
44 | | - manager = new GameInstanceManager(user); |
45 | | - } |
46 | | - exitCode = options.Handle(manager, user); |
47 | | - if (exitCode == Exit.OK) |
48 | | - { |
49 | | - switch (option) |
50 | | - { |
51 | | - case "list": |
52 | | - exitCode = listAuthTokens(options); |
53 | | - break; |
54 | | - case "add": |
55 | | - exitCode = addAuthToken((AddAuthTokenOptions)options); |
56 | | - break; |
57 | | - case "remove": |
58 | | - exitCode = removeAuthToken((RemoveAuthTokenOptions)options); |
59 | | - break; |
60 | | - } |
61 | | - } |
62 | | - } |
63 | | - }, () => { exitCode = MainClass.AfterHelp(); }); |
| 36 | + case "AddAuthToken": |
| 37 | + exitCode = AddAuthToken(args); |
| 38 | + break; |
| 39 | + case "ListAuthToken": |
| 40 | + exitCode = ListAuthTokens(); |
| 41 | + break; |
| 42 | + case "RemoveAuthToken": |
| 43 | + exitCode = RemoveAuthToken(args); |
| 44 | + break; |
| 45 | + default: |
| 46 | + exitCode = Exit.BadOpt; |
| 47 | + break; |
| 48 | + } |
| 49 | + |
64 | 50 | return exitCode; |
65 | 51 | } |
66 | 52 |
|
67 | | - private int listAuthTokens(CommonOptions opts) |
| 53 | + /// <inheritdoc cref="ISubCommand.GetUsage"/> |
| 54 | + public string GetUsage(string prefix, string[] args) |
68 | 55 | { |
69 | | - List<string> hosts = new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()); |
70 | | - if (hosts.Count > 0) |
| 56 | + if (args.Length == 1) |
| 57 | + return $"{prefix} {args[0]} <command> [options]"; |
| 58 | + |
| 59 | + switch (args[1]) |
71 | 60 | { |
72 | | - int longestHostLen = hostHeader.Length; |
73 | | - int longestTokenLen = tokenHeader.Length; |
74 | | - foreach (string host in hosts) |
75 | | - { |
76 | | - longestHostLen = Math.Max(longestHostLen, host.Length); |
77 | | - string token; |
78 | | - if (ServiceLocator.Container.Resolve<IConfiguration>().TryGetAuthToken(host, out token)) |
79 | | - { |
80 | | - longestTokenLen = Math.Max(longestTokenLen, token.Length); |
81 | | - } |
82 | | - } |
83 | | - // Create format string: {0,-longestHostLen} {1,-longestTokenLen} |
84 | | - string fmt = string.Format("{0}0,-{2}{1} {0}1,-{3}{1}", |
85 | | - "{", "}", longestHostLen, longestTokenLen); |
86 | | - user.RaiseMessage(fmt, hostHeader, tokenHeader); |
87 | | - user.RaiseMessage(fmt, |
88 | | - new string('-', longestHostLen), |
89 | | - new string('-', longestTokenLen) |
90 | | - ); |
91 | | - foreach (string host in hosts) |
92 | | - { |
93 | | - string token; |
94 | | - if (ServiceLocator.Container.Resolve<IConfiguration>().TryGetAuthToken(host, out token)) |
95 | | - { |
96 | | - user.RaiseMessage(fmt, host, token); |
97 | | - } |
98 | | - } |
| 61 | + case "add": |
| 62 | + return $"{prefix} {args[0]} {args[1]} [options] <host> <token>"; |
| 63 | + case "list": |
| 64 | + return $"{prefix} {args[0]} {args[1]} [options]"; |
| 65 | + case "remove": |
| 66 | + return $"{prefix} {args[0]} {args[1]} [options] <host>"; |
| 67 | + default: |
| 68 | + return $"{prefix} {args[0]} <command> [options]"; |
99 | 69 | } |
100 | | - return Exit.OK; |
101 | 70 | } |
102 | 71 |
|
103 | | - private int addAuthToken(AddAuthTokenOptions opts) |
| 72 | + private int AddAuthToken(object args) |
104 | 73 | { |
105 | | - if (Uri.CheckHostName(opts.host) != UriHostNameType.Unknown) |
| 74 | + var opts = (AuthTokenOptions.AddAuthToken)args; |
| 75 | + if (opts.Host == null || opts.Token == null) |
106 | 76 | { |
107 | | - ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(opts.host, opts.token); |
| 77 | + _user.RaiseMessage("add <host> <token> - argument(s) missing, perhaps you forgot it?"); |
| 78 | + return Exit.BadOpt; |
| 79 | + } |
| 80 | + |
| 81 | + if (Uri.CheckHostName(opts.Host) != UriHostNameType.Unknown) |
| 82 | + { |
| 83 | + ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(opts.Host, opts.Token); |
| 84 | + _user.RaiseMessage("Successfully added \"{0}\".", opts.Host); |
108 | 85 | } |
109 | 86 | else |
110 | 87 | { |
111 | | - user.RaiseError("Invalid host name: {0}", opts.host); |
| 88 | + _user.RaiseMessage("Invalid host name."); |
| 89 | + return Exit.BadOpt; |
112 | 90 | } |
113 | | - return Exit.OK; |
| 91 | + |
| 92 | + return Exit.Ok; |
114 | 93 | } |
115 | 94 |
|
116 | | - private int removeAuthToken(RemoveAuthTokenOptions opts) |
| 95 | + private int ListAuthTokens() |
117 | 96 | { |
118 | | - ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(opts.host, null); |
119 | | - return Exit.OK; |
120 | | - } |
| 97 | + const string hostHeader = "Host"; |
| 98 | + const string tokenHeader = "Token"; |
121 | 99 |
|
122 | | - private const string hostHeader = "Host"; |
123 | | - private const string tokenHeader = "Token"; |
| 100 | + var hosts = new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()); |
| 101 | + if (hosts.Count > 0) |
| 102 | + { |
| 103 | + var hostWidth = hostHeader.Length; |
| 104 | + var tokenWidth = tokenHeader.Length; |
| 105 | + foreach (var host in hosts) |
| 106 | + { |
| 107 | + hostWidth = Math.Max(hostWidth, host.Length); |
| 108 | + if (ServiceLocator.Container.Resolve<IConfiguration>().TryGetAuthToken(host, out string token) && token != null) |
| 109 | + { |
| 110 | + tokenWidth = Math.Max(tokenWidth, token.Length); |
| 111 | + } |
| 112 | + } |
124 | 113 |
|
125 | | - private IUser user; |
126 | | - private static readonly ILog log = LogManager.GetLogger(typeof(AuthToken)); |
127 | | - } |
| 114 | + _user.RaiseMessage("{0} {1}", |
| 115 | + hostHeader.PadRight(hostWidth), |
| 116 | + tokenHeader.PadRight(tokenWidth) |
| 117 | + ); |
128 | 118 |
|
129 | | - internal class AuthTokenSubOptions : VerbCommandOptions |
130 | | - { |
131 | | - [VerbOption("list", HelpText = "List auth tokens")] |
132 | | - public CommonOptions ListOptions { get; set; } |
| 119 | + _user.RaiseMessage("{0} {1}", |
| 120 | + new string('-', hostWidth), |
| 121 | + new string('-', tokenWidth) |
| 122 | + ); |
133 | 123 |
|
134 | | - [VerbOption("add", HelpText = "Add an auth token")] |
135 | | - public AddAuthTokenOptions AddOptions { get; set; } |
| 124 | + foreach (var host in hosts) |
| 125 | + { |
| 126 | + if (ServiceLocator.Container.Resolve<IConfiguration>().TryGetAuthToken(host, out string token)) |
| 127 | + { |
| 128 | + _user.RaiseMessage("{0} {1}", |
| 129 | + host.PadRight(hostWidth), |
| 130 | + token.PadRight(tokenWidth) |
| 131 | + ); |
| 132 | + } |
| 133 | + } |
| 134 | + } |
136 | 135 |
|
137 | | - [VerbOption("remove", HelpText = "Delete an auth token")] |
138 | | - public RemoveAuthTokenOptions RemoveOptions { get; set; } |
| 136 | + return Exit.Ok; |
| 137 | + } |
139 | 138 |
|
140 | | - [HelpVerbOption] |
141 | | - public string GetUsage(string verb) |
| 139 | + private int RemoveAuthToken(object args) |
142 | 140 | { |
143 | | - HelpText ht = HelpText.AutoBuild(this, verb); |
144 | | - // Add a usage prefix line |
145 | | - ht.AddPreOptionsLine(" "); |
146 | | - if (string.IsNullOrEmpty(verb)) |
| 141 | + var opts = (AuthTokenOptions.RemoveAuthToken)args; |
| 142 | + if (opts.Host == null) |
147 | 143 | { |
148 | | - ht.AddPreOptionsLine("ckan authtoken - Manage authentication tokens"); |
149 | | - ht.AddPreOptionsLine($"Usage: ckan authtoken <command> [options]"); |
| 144 | + _user.RaiseMessage("remove <host> - argument missing, perhaps you forgot it?"); |
| 145 | + return Exit.BadOpt; |
| 146 | + } |
| 147 | + |
| 148 | + var hosts = new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()); |
| 149 | + if (hosts.Contains(opts.Host)) |
| 150 | + { |
| 151 | + ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(opts.Host, null); |
| 152 | + _user.RaiseMessage("Successfully removed \"{0}\".", opts.Host); |
150 | 153 | } |
151 | 154 | else |
152 | 155 | { |
153 | | - ht.AddPreOptionsLine("authtoken " + verb + " - " + GetDescription(verb)); |
154 | | - switch (verb) |
155 | | - { |
156 | | - case "add": |
157 | | - ht.AddPreOptionsLine($"Usage: ckan authtoken {verb} [options] host token"); |
158 | | - break; |
159 | | - case "remove": |
160 | | - ht.AddPreOptionsLine($"Usage: ckan authtoken {verb} [options] host"); |
161 | | - break; |
162 | | - case "list": |
163 | | - ht.AddPreOptionsLine($"Usage: ckan authtoken {verb} [options]"); |
164 | | - break; |
165 | | - } |
| 156 | + _user.RaiseMessage("There is no host with the name \"{0}\".", opts.Host); |
| 157 | + _user.RaiseMessage("Use 'ckan authtoken list' to view a list of hosts."); |
| 158 | + return Exit.BadOpt; |
166 | 159 | } |
167 | | - return ht; |
| 160 | + |
| 161 | + return Exit.Ok; |
168 | 162 | } |
169 | 163 | } |
170 | 164 |
|
171 | | - internal class AddAuthTokenOptions : CommonOptions |
| 165 | + [Verb("authtoken", HelpText = "Manage authentication tokens")] |
| 166 | + [ChildVerbs(typeof(AddAuthToken), typeof(ListAuthToken), typeof(RemoveAuthToken))] |
| 167 | + internal class AuthTokenOptions |
172 | 168 | { |
173 | | - [ValueOption(0)] public string host { get; set; } |
174 | | - [ValueOption(1)] public string token { get; set; } |
175 | | - } |
| 169 | + [VerbExclude] |
| 170 | + [Verb("add", HelpText = "Add an authentication token")] |
| 171 | + internal class AddAuthToken : CommonOptions |
| 172 | + { |
| 173 | + [Value(0, MetaName = "Host", HelpText = "The host (DNS / IP) to authenticate with")] |
| 174 | + public string Host { get; set; } |
176 | 175 |
|
177 | | - internal class RemoveAuthTokenOptions : CommonOptions |
178 | | - { |
179 | | - [ValueOption(0)] public string host { get; set; } |
180 | | - } |
| 176 | + [Value(1, MetaName = "Token", HelpText = "The token to authenticate with")] |
| 177 | + public string Token { get; set; } |
| 178 | + } |
| 179 | + |
| 180 | + [VerbExclude] |
| 181 | + [Verb("list", HelpText = "List authentication tokens")] |
| 182 | + internal class ListAuthToken : CommonOptions { } |
181 | 183 |
|
| 184 | + [VerbExclude] |
| 185 | + [Verb("remove", HelpText = "Remove an authentication token")] |
| 186 | + internal class RemoveAuthToken : CommonOptions |
| 187 | + { |
| 188 | + [Value(0, MetaName = "Host", HelpText = "The host (DNS / IP) to remove")] |
| 189 | + public string Host { get; set; } |
| 190 | + } |
| 191 | + } |
182 | 192 | } |
0 commit comments