Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 0cd7856

Browse files
author
Irene
committed
Add login prompt on server address change
1 parent 49a1ff7 commit 0cd7856

File tree

6 files changed

+73
-51
lines changed

6 files changed

+73
-51
lines changed

docs/MANUAL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ List of configurable settings:
207207
* *send-analytics*
208208
Allow sending analytics data of commands run. Stored in account.
209209
* *server-address*
210-
Address to fetch courses from and submit to. Defaults to `https://tmc.mooc.fi`. Stored with account.
210+
Address to fetch courses from and submit to. Defaults to `https://tmc.mooc.fi`. Stored with account. Changing the server address will log the user out and prompt a new login.
211211

212212
COMMAND: ORGANIZATION
213213
---------------

src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.slf4j.Logger;
2121
import org.slf4j.LoggerFactory;
2222

23+
import javax.swing.text.html.Option;
2324
import java.nio.file.Path;
2425
import java.util.Locale;
2526
import java.util.concurrent.Callable;
@@ -74,7 +75,7 @@ private boolean migrateAccount(CliContext context, Account account) throws Excep
7475
io.println("TMC cli has been updated. Please provide the following information.");
7576
if (!context.getSettings().getOrganization().isPresent()) {
7677
OrganizationCommand organizationCommand = new OrganizationCommand();
77-
Optional<Organization> organization = organizationCommand.chooseOrganization(context, null);
78+
Optional<Organization> organization = organizationCommand.chooseOrganization(context, Optional.absent());
7879
if (!organization.isPresent()) {
7980
return false;
8081
}
@@ -83,12 +84,12 @@ private boolean migrateAccount(CliContext context, Account account) throws Excep
8384
Callable<Void> callable = context.getTmcCore().authenticate(ProgressObserver.NULL_OBSERVER, account.getPassword().get());
8485
callable.call();
8586
LoginCommand loginCommand = new LoginCommand();
86-
boolean sendDiagnostics = loginCommand.getAnswerFromUser(null, account.getServerAddress(),
87+
boolean sendDiagnostics = loginCommand.getBooleanAnswerFromUser(Optional.absent(),
8788
"Do you want to send crash reports for client development?",
8889
false,
8990
io);
9091
account.setSendDiagnostics(sendDiagnostics);
91-
boolean sendAnalytics = loginCommand.getAnswerFromUser(null, account.getServerAddress(),
92+
boolean sendAnalytics = loginCommand.getBooleanAnswerFromUser(Optional.absent(),
9293
"Do you want to send analytics data for research?",
9394
false,
9495
io);

src/main/java/fi/helsinki/cs/tmc/cli/command/ConfigCommand.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import fi.helsinki.cs.tmc.cli.core.AbstractCommand;
66
import fi.helsinki.cs.tmc.cli.core.CliContext;
77
import fi.helsinki.cs.tmc.cli.core.Command;
8+
import fi.helsinki.cs.tmc.cli.core.CommandFactory;
89
import fi.helsinki.cs.tmc.cli.io.Io;
910

1011
import fi.helsinki.cs.tmc.cli.utils.BadValueTypeException;
@@ -84,6 +85,10 @@ public void setter(String value) throws BadValueTypeException {
8485
context.getSettings().setServerAddress(addr);
8586
normalizeServerAddress();
8687
SettingsIo.saveCurrentSettingsToAccountList(context.getSettings());
88+
io.println("Please login again to use the new server.");
89+
SettingsIo.delete();
90+
LoginCommand loginCommand = new LoginCommand();
91+
loginCommand.login(context, null, Optional.of(value));
8792
}
8893
});
8994
ALLOWED_KEYS.put(testResultRightKey, new PropertyFunctions() {

src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import fi.helsinki.cs.tmc.core.domain.Organization;
1414
import org.apache.commons.cli.CommandLine;
15+
import org.apache.commons.cli.Option;
1516
import org.apache.commons.cli.Options;
1617

1718
import com.google.common.base.Optional;
@@ -49,9 +50,11 @@ public void run(CliContext context, CommandLine args) {
4950
}
5051

5152
if (this.ctx.checkIsLoggedIn(true, true)) {
52-
io.println("You are already logged in as " + this.ctx.getSettings().getUsername().get() +
53-
(this.ctx.getSettings().getOrganization().isPresent() ?
54-
" and your current organization is " + this.ctx.getSettings().getOrganization().get().getName() :
53+
Optional<String> username = this.ctx.getSettings().getUsername();
54+
Optional<Organization> organization = this.ctx.getSettings().getOrganization();
55+
io.println("You are already logged in " + (username.isPresent()? "as " + username.get() : "") +
56+
(organization.isPresent() ?
57+
" and your current organization is " + organization.get().getName() :
5558
"."));
5659
io.println("Change your organization with the command organization.");
5760
io.println("Inspect and change your current settings with the command config.");
@@ -69,31 +72,40 @@ public void run(CliContext context, CommandLine args) {
6972
username = info.getUsername();
7073
}
7174

72-
username = getLoginInfo(args, username, "u", "username: ");
73-
password = getLoginInfo(args, null, "p", "password: ");
75+
login(this.ctx, args, Optional.absent());
76+
}
77+
78+
public void login(CliContext ctx, CommandLine args, Optional<String> serverAddress) {
79+
Io io = ctx.getIo();
80+
username = getLoginInfo(args, username, "u", "username: ", io);
81+
password = getLoginInfo(args, null, "p", "password: ", io);
82+
7483

7584
Account account = new Account(username);
85+
if (serverAddress.isPresent()) {
86+
account.setServerAddress(serverAddress.get());
87+
}
7688
ctx.useAccount(account);
7789

7890
if (!TmcUtil.tryToLogin(ctx, account, password)) {
79-
this.ctx.getSettings().setAccount(this.ctx, new Account());
91+
ctx.getSettings().setAccount(ctx, new Account());
8092
return;
8193
}
8294

8395
OrganizationCommand organizationCommand = new OrganizationCommand();
84-
Optional<Organization> organization = organizationCommand.chooseOrganization(ctx, args);
96+
Optional<Organization> organization = organizationCommand.chooseOrganization(ctx, Optional.of(args));
8597
if (!organization.isPresent()) {
8698
return;
8799
}
88100
account.setOrganization(organization);
89101

90-
boolean sendDiagnostics = getAnswerFromUser(username, account.getServerAddress(),
91-
"Do you want to send crash reports for client development?",
92-
this.ctx.getSettings().getSendDiagnostics(), this.io);
102+
boolean sendDiagnostics = getBooleanAnswerFromUser(Optional.of(username),
103+
"Do you want to send crash reports for client development?",
104+
ctx.getSettings().getSendDiagnostics(), io);
93105
account.setSendDiagnostics(sendDiagnostics);
94-
boolean sendAnalytics = getAnswerFromUser(username, account.getServerAddress(),
95-
"Do you want to send analytics data for research?",
96-
this.ctx.getSettings().isSpywareEnabled(), this.io);
106+
boolean sendAnalytics = getBooleanAnswerFromUser(Optional.of(username),
107+
"Do you want to send analytics data for research?",
108+
ctx.getSettings().isSpywareEnabled(), io);
97109
account.setSendAnalytics(sendAnalytics);
98110

99111
AccountList list = SettingsIo.loadAccountList();
@@ -103,18 +115,18 @@ public void run(CliContext context, CommandLine args) {
103115
return;
104116
}
105117

106-
this.ctx.getAnalyticsFacade().saveAnalytics("login");
118+
ctx.getAnalyticsFacade().saveAnalytics("login");
107119

108120
io.println("Login successful.");
109121
io.println("You can change your organization with the command organization, " +
110122
"and inspect and change other settings with the command config.");
111123
}
112124

113-
private String getLoginInfo(CommandLine line, String oldValue, String option, String prompt) {
125+
private String getLoginInfo(CommandLine line, String oldValue, String option, String prompt, Io io) {
114126
String value = oldValue;
115127
boolean isPassword = option.equals("p");
116128

117-
if (line.hasOption(option)) {
129+
if (line != null && line.hasOption(option)) {
118130
value = line.getOptionValue(option);
119131
}
120132

@@ -130,9 +142,9 @@ private String getLoginInfo(CommandLine line, String oldValue, String option, St
130142
return value;
131143
}
132144

133-
public boolean getAnswerFromUser(String username, String server, String prompt, boolean defaultValue, Io io) {
145+
public boolean getBooleanAnswerFromUser(Optional<String> username, String prompt, boolean defaultValue, Io io) {
134146
AccountList savedAccounts = SettingsIo.loadAccountList();
135-
if (username != null && savedAccounts.getAccount(username) != null) {
147+
if (username.isPresent() && savedAccounts.getAccount(username.get()) != null) {
136148
// not the first time logging in
137149
return defaultValue;
138150
}

src/main/java/fi/helsinki/cs/tmc/cli/command/OrganizationCommand.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import fi.helsinki.cs.tmc.cli.utils.OptionalToGoptional;
1111
import fi.helsinki.cs.tmc.core.domain.Organization;
1212
import org.apache.commons.cli.CommandLine;
13+
import org.apache.commons.cli.Option;
1314
import org.apache.commons.cli.Options;
1415

1516
import java.util.ArrayList;
@@ -37,7 +38,7 @@ public void run(CliContext ctx, CommandLine args) {
3738

3839
this.ctx.getAnalyticsFacade().saveAnalytics("organization");
3940

40-
Optional<Organization> organization = chooseOrganization(ctx, args);
41+
Optional<Organization> organization = chooseOrganization(ctx, Optional.of(args));
4142
this.ctx.getSettings().setOrganization(organization);
4243
SettingsIo.saveCurrentSettingsToAccountList(this.ctx.getSettings());
4344
}
@@ -80,24 +81,24 @@ private void printFormattedOrganization(Organization o) {
8081
}
8182

8283

83-
private String getOrganizationFromUser(List<Organization> organizations, CommandLine line, boolean printOptions, boolean oneLine) {
84-
if (oneLine && line != null && line.hasOption("o")) {
85-
return line.getOptionValue("o");
84+
private String getOrganizationFromUser(List<Organization> organizations, Optional<CommandLine> line, boolean printOptions, boolean oneLine) {
85+
if (oneLine && line.isPresent() && line.get().hasOption("o")) {
86+
return line.get().getOptionValue("o");
8687
}
8788
if (printOptions) {
88-
printOrganizations(organizations, line != null && !line.hasOption("n") && !EnvironmentUtil.isWindows());
89+
printOrganizations(organizations, line.isPresent() && !line.get().hasOption("n") && !EnvironmentUtil.isWindows());
8990
}
9091
return io.readLine("Choose an organization by writing its slug: ");
9192
}
9293

9394

94-
public Optional<Organization> chooseOrganization(CliContext ctx, CommandLine args) {
95+
public Optional<Organization> chooseOrganization(CliContext ctx, Optional<CommandLine> args) {
9596
this.ctx = ctx;
9697
this.io = ctx.getIo();
9798
boolean printOptions = true;
9899
boolean oneLine = false;
99-
if (args != null) {
100-
oneLine = args.hasOption("o");
100+
if (args.isPresent()) {
101+
oneLine = args.get().hasOption("o");
101102
}
102103
List<Organization> organizations = listOrganizations();
103104
if (organizations == null || organizations.isEmpty()) {

src/test/java/fi/helsinki/cs/tmc/cli/command/ConfigCommandTest.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,21 @@
33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.assertTrue;
55
import static org.mockito.Matchers.any;
6+
import static org.mockito.Matchers.eq;
67
import static org.mockito.Mockito.doReturn;
78
import static org.mockito.Mockito.spy;
89
import static org.mockito.Mockito.when;
910
import static org.powermock.api.mockito.PowerMockito.mockStatic;
1011

1112
import fi.helsinki.cs.tmc.cli.Application;
1213
import fi.helsinki.cs.tmc.cli.analytics.AnalyticsFacade;
13-
import fi.helsinki.cs.tmc.cli.backend.Account;
14-
import fi.helsinki.cs.tmc.cli.backend.AccountList;
15-
import fi.helsinki.cs.tmc.cli.backend.Settings;
16-
import fi.helsinki.cs.tmc.cli.backend.SettingsIo;
14+
import fi.helsinki.cs.tmc.cli.backend.*;
1715
import fi.helsinki.cs.tmc.cli.core.CliContext;
1816
import fi.helsinki.cs.tmc.cli.io.TestIo;
1917

2018
import fi.helsinki.cs.tmc.cli.io.WorkDir;
2119
import fi.helsinki.cs.tmc.core.TmcCore;
20+
import fi.helsinki.cs.tmc.core.domain.Organization;
2221
import fi.helsinki.cs.tmc.langs.util.TaskExecutor;
2322
import fi.helsinki.cs.tmc.langs.util.TaskExecutorImpl;
2423
import fi.helsinki.cs.tmc.spyware.EventSendBuffer;
@@ -35,10 +34,11 @@
3534
import java.io.IOException;
3635
import java.nio.file.Files;
3736
import java.nio.file.Path;
37+
import java.util.ArrayList;
3838
import java.util.HashMap;
3939

4040
@RunWith(PowerMockRunner.class)
41-
@PrepareForTest(SettingsIo.class)
41+
@PrepareForTest({ SettingsIo.class, TmcUtil.class })
4242
public class ConfigCommandTest {
4343

4444
private Application app;
@@ -69,7 +69,11 @@ public void setup() throws IOException {
6969
when(ctx.getSettings()).thenReturn(settings);
7070
testConfigRoot = Files.createTempDirectory(".test-config");
7171
mockStatic(SettingsIo.class);
72+
mockStatic(TmcUtil.class);
7273
when(SettingsIo.getPropertiesFile(any(Path.class))).thenReturn(testConfigRoot.resolve(TEST_PROPERTIES_FILENAME));
74+
ArrayList<Organization> organizationList = new ArrayList<>();
75+
organizationList.add(new Organization("Test", "", "test", "", false));
76+
when(TmcUtil.getOrganizationsFromServer(any(CliContext.class))).thenReturn(organizationList);
7377
when(SettingsIo.getConfigDirectory()).thenReturn(testConfigRoot);
7478
AccountList t = new AccountList();
7579
t.addAccount(new Account("username", ""));
@@ -271,13 +275,6 @@ public void sendDiagnosticsIsAllowed() {
271275
io.assertContains("Set send-diagnostics to");
272276
}
273277

274-
@Test
275-
public void serverAddressIsAllowed() {
276-
io.addConfirmationPrompt(true);
277-
app.run(new String[] {"config", "server-address=https://mooc.fi"});
278-
io.assertContains("Set server-address to");
279-
}
280-
281278
@Test
282279
public void printsErrorWithTooFewArgumentsa() {
283280
app.run(new String[] {"config", "inValid"});
@@ -305,8 +302,14 @@ public void sendDiagnosticsIsValidated() {
305302
}
306303

307304
@Test
308-
public void serverAddressConfiguredToSettings() {
305+
public void serverAddressConfiguredToSettingsAndPromptsLogin() {
306+
when(TmcUtil.tryToLogin(eq(ctx), any(Account.class), any(String.class))).thenReturn(true);
309307
io.addConfirmationPrompt(true);
308+
io.addLinePrompt("test");
309+
io.addPasswordPrompt("password");
310+
io.addLinePrompt("test");
311+
io.addLinePrompt("yes");
312+
io.addLinePrompt("yes");
310313
app.run(new String[] {"config", "server-address=https://mooc.fi"});
311314
assertEquals("https://mooc.fi", settings.getServerAddress());
312315
}
@@ -328,32 +331,32 @@ public void configuredToSettingsWithQuiet() {
328331
public void ifSeveralPairsAndSomeInvalidConfiguresValidOnes() {
329332
io.addConfirmationPrompt(true);
330333
io.addConfirmationPrompt(true);
331-
app.run(new String[] {"config", "send-diagnostics=asdf", "server-address=https://mooc.fi"});
334+
app.run(new String[] {"config", "send-diagnostics=asdf", "send-diagnostics=true"});
332335
io.assertContains("Please write either true or false");
333-
assertEquals("https://mooc.fi", settings.getServerAddress());
336+
assertEquals(true, settings.getSendDiagnostics());
334337
}
335338

336339
@Test
337340
public void ifSeveralPairsAndSomeInvalidValuesConfiguresValidOnesWithQuiet() {
338-
app.run(new String[] {"config", "-q", "send-diagnostics=asdf", "server-address=https://mooc.fi"});
341+
app.run(new String[] {"config", "-q", "send-analytics=asdf", "send-diagnostics=true"});
339342
io.assertContains("Please write either true or false");
340-
assertEquals("https://mooc.fi", settings.getServerAddress());
343+
assertEquals(true, settings.getSendDiagnostics());
341344
}
342345

343346
@Test
344347
public void ifSeveralPairsAndSomeInvalidKeysConfiguresValidOnes() {
345348
io.addConfirmationPrompt(true);
346349
io.addConfirmationPrompt(true);
347-
app.run(new String[] {"config", "asd=asdf", "server-address=https://mooc.fi"});
350+
app.run(new String[] {"config", "asd=asdf", "send-diagnostics=true"});
348351
io.assertContains("not an allowed key");
349-
assertEquals("https://mooc.fi", settings.getServerAddress());
352+
assertEquals(true, settings.getSendDiagnostics());
350353
}
351354

352355
@Test
353356
public void ifSeveralPairsAndSomeInvalidKeysConfiguresValidOnesWithQuiet() {
354-
app.run(new String[] {"config", "-q", "asd=asdf", "server-address=https://mooc.fi"});
357+
app.run(new String[] {"config", "-q", "asd=asdf", "send-diagnostics=true"});
355358
io.assertContains("not an allowed key");
356-
assertEquals("https://mooc.fi", settings.getServerAddress());
359+
assertEquals(true, settings.getSendDiagnostics());
357360
}
358361

359362
@Test

0 commit comments

Comments
 (0)