1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package davmail.exchange.auth;
21
22 import davmail.BundleMessage;
23 import davmail.Settings;
24 import davmail.ui.tray.DavGatewayTray;
25 import davmail.ui.tray.SwtGatewayTray;
26 import org.apache.log4j.Logger;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.SWTError;
29 import org.eclipse.swt.browser.Browser;
30 import org.eclipse.swt.browser.LocationEvent;
31 import org.eclipse.swt.browser.LocationListener;
32 import org.eclipse.swt.layout.FillLayout;
33 import org.eclipse.swt.widgets.Display;
34 import org.eclipse.swt.widgets.Shell;
35
36
37
38
39 public class O365InteractiveAuthenticatorSWT {
40
41 private static final Logger LOGGER = Logger.getLogger(O365InteractiveAuthenticatorSWT.class);
42
43 private O365InteractiveAuthenticator authenticator;
44
45 Shell shell;
46 Browser browser;
47 private final Object LOCK = new Object();
48 private boolean isReady = false;
49 private SWTError error;
50
51 public O365InteractiveAuthenticatorSWT() {
52
53 }
54
55 public void setO365InteractiveAuthenticator(O365InteractiveAuthenticator authenticator) {
56 this.authenticator = authenticator;
57 }
58
59 public void authenticate(final String initUrl, final String redirectUri) {
60
61 SwtGatewayTray.initDisplay();
62
63
64 System.setProperty("org.eclipse.swt.browser.Edge.allowSingleSignOnUsingOSPrimaryAccount",
65 Settings.getProperty("davmail.oauth.allowSingleSignOnUsingOSPrimaryAccount", "true"));
66
67 Display.getDefault().asyncExec(() -> {
68 try {
69 shell = new Shell(Display.getDefault());
70 shell.setText(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
71 shell.setSize(600, 600);
72
73 shell.setLayout(new FillLayout());
74
75 shell.setImage(SwtGatewayTray.loadSwtImage("tray.png", 32));
76
77 shell.addListener(SWT.Close, event -> {
78 if (!authenticator.isAuthenticated && authenticator.errorCode == null) {
79 authenticator.errorCode = "user closed authentication window";
80 }
81 dispose();
82 });
83
84 browser = new Browser(shell, SWT.NONE);
85
86 browser.setUrl(initUrl);
87 browser.addTitleListener(titleEvent -> shell.setText("DavMail: " + titleEvent.title));
88 browser.addLocationListener(new LocationListener() {
89 @Override
90 public void changing(LocationEvent locationEvent) {
91 LOGGER.debug("Navigate to " + locationEvent.toString());
92 String location = locationEvent.location;
93
94 if (location.startsWith(redirectUri)) {
95
96 LOGGER.debug("Location starts with redirectUri, check code");
97 authenticator.handleCode(location);
98
99 shell.close();
100 dispose();
101 }
102
103 }
104
105 @Override
106 public void changed(LocationEvent locationEvent) {
107 LOGGER.debug("Page changed: " + locationEvent.toString());
108 }
109 });
110
111 synchronized (LOCK) {
112
113 isReady = true;
114 LOCK.notifyAll();
115 }
116
117 shell.open();
118 shell.setActive();
119 } catch (SWTError e) {
120 error = e;
121 }
122
123 });
124
125 while (true) {
126
127 try {
128 synchronized (LOCK) {
129 if (error != null) {
130 throw error;
131 }
132 if (isReady) {
133 break;
134 }
135 LOCK.wait(1000);
136 }
137 } catch (InterruptedException e) {
138 DavGatewayTray.error(new BundleMessage("LOG_ERROR_WAITING_FOR_SWT_INIT"), e);
139 Thread.currentThread().interrupt();
140 }
141 }
142
143 }
144
145 protected void dispose() {
146 Display.getDefault().asyncExec(() -> {
147 if (browser != null) {
148 browser.dispose();
149 }
150 if (shell != null) {
151 shell.dispose();
152 }
153 });
154 }
155 }