Преглед на файлове

Initial work on QAuth plugin.

pull/300/head
Greg Holmes преди 9 години
родител
ревизия
984dfdf6db
променени са 2 файла, в които са добавени 356 реда и са изтрити 3 реда
  1. 145
    3
      qauth/src/com/dmdirc/addons/qauth/QAuthManager.java
  2. 211
    0
      qauth/test/com/dmdirc/addons/qauth/QAuthManagerTest.java

+ 145
- 3
qauth/src/com/dmdirc/addons/qauth/QAuthManager.java Целия файл

@@ -22,12 +22,32 @@
22 22
 
23 23
 package com.dmdirc.addons.qauth;
24 24
 
25
+import com.dmdirc.ClientModule.GlobalConfig;
26
+import com.dmdirc.DMDircMBassador;
27
+import com.dmdirc.Invite;
28
+import com.dmdirc.config.ConfigBinder;
29
+import com.dmdirc.config.ConfigBinding;
30
+import com.dmdirc.config.prefs.PluginPreferencesCategory;
31
+import com.dmdirc.config.prefs.PreferencesSetting;
32
+import com.dmdirc.config.prefs.PreferencesType;
25 33
 import com.dmdirc.events.ClientPrefsOpenedEvent;
34
+import com.dmdirc.events.QueryMessageEvent;
35
+import com.dmdirc.events.ServerConnectedEvent;
36
+import com.dmdirc.events.ServerInviteReceivedEvent;
37
+import com.dmdirc.events.ServerNoticeEvent;
38
+import com.dmdirc.interfaces.Connection;
39
+import com.dmdirc.interfaces.User;
40
+import com.dmdirc.interfaces.config.AggregateConfigProvider;
26 41
 import com.dmdirc.plugins.PluginDomain;
27 42
 import com.dmdirc.plugins.PluginInfo;
43
+import com.dmdirc.util.validators.NotEmptyValidator;
44
+
45
+import java.util.Optional;
28 46
 
29 47
 import javax.inject.Inject;
30 48
 
49
+import net.engio.mbassy.listener.Handler;
50
+
31 51
 /**
32 52
  * Provides Q AUth support in DMDirc.
33 53
  */
@@ -35,22 +55,144 @@ public class QAuthManager {
35 55
 
36 56
     private final String domain;
37 57
     private final PluginInfo pluginInfo;
58
+    private final DMDircMBassador eventBus;
59
+    private final ConfigBinder configBinder;
60
+    private String username;
61
+    private String password;
62
+    private boolean whois;
63
+    private boolean autoInvite;
64
+    private boolean acceptInvites;
38 65
 
39 66
     @Inject
40 67
     public QAuthManager(
41 68
             @PluginDomain(QAuthPlugin.class) final String domain,
42
-            @PluginDomain(QAuthPlugin.class) final PluginInfo pluginInfo) {
69
+            @PluginDomain(QAuthPlugin.class) final PluginInfo pluginInfo,
70
+            @GlobalConfig final AggregateConfigProvider config,
71
+            final DMDircMBassador eventBus) {
43 72
         this.domain = domain;
44 73
         this.pluginInfo = pluginInfo;
74
+        this.eventBus = eventBus;
75
+        configBinder = config.getBinder().withDefaultDomain(domain);
45 76
     }
46 77
 
47 78
     public void load() {
79
+        configBinder.bind(this, QAuthManager.class);
80
+        eventBus.subscribe(this);
48 81
     }
49 82
 
50 83
     public void unload() {
84
+        configBinder.unbind(this);
85
+        eventBus.unsubscribe(this);
86
+    }
87
+
88
+    private boolean isValidConnection(final Connection connection) {
89
+        return "Quakenet".equals(connection.getNetwork());
90
+    }
91
+
92
+    private boolean isValidUser(final User user) {
93
+        // TODO: Check hostname?
94
+        return "Q".equals(user.getNickname());
95
+    }
96
+
97
+    private void acceptInvite(final Invite invite) {
98
+        invite.accept();
99
+    }
100
+
101
+    private void requestInvites(final Connection connection) {
102
+        connection.sendMessage("Q@Cserve.quakenet.org", "invite");
103
+    }
104
+
105
+    private void auth(final Connection connection) {
106
+        connection.sendMessage("Q@Cserve.quakenet.org", "auth " + username + ' ' + password);
107
+    }
108
+
109
+    @Handler
110
+    void handleConnect(final ServerConnectedEvent event) {
111
+        if (!isValidConnection(event.getConnection())) {
112
+            return;
113
+        }
114
+        // TODO: whois
115
+        auth(event.getConnection());
116
+    }
117
+
118
+    @Handler
119
+    void handleInvite(final ServerInviteReceivedEvent event) {
120
+        if (!acceptInvites) {
121
+            return;
122
+        }
123
+        if (isValidConnection(event.getConnection()) && isValidUser(event.getUser())) {
124
+            acceptInvite(event.getInvite());
125
+        }
126
+    }
127
+
128
+    @Handler
129
+    void handleNotices(final ServerNoticeEvent event) {
130
+        handleCommunication(Optional.of(event.getConnection()), event.getUser(), event.getMessage());
131
+    }
132
+
133
+    @Handler
134
+    void handleMessages(final QueryMessageEvent event) {
135
+        handleCommunication(event.getQuery().getConnection(), event.getUser(), event.getMessage());
136
+    }
137
+
138
+    private void handleCommunication(final Optional<Connection> connection, final User user,
139
+            final String message) {
140
+        connection.ifPresent(c -> {
141
+            if (isValidConnection(c) && isValidUser(user) &&
142
+                    ("You are now logged in as " + username + '.').equalsIgnoreCase(message)) {
143
+                if (autoInvite) {
144
+                    requestInvites(c);
145
+                }
146
+            }
147
+        });
148
+    }
149
+
150
+    @ConfigBinding(key = "username")
151
+    void handleUsername(final String value) {
152
+        username = value;
153
+    }
154
+
155
+    @ConfigBinding(key = "password")
156
+    void handlePassword(final String value) {
157
+        password = value;
158
+    }
159
+
160
+    @ConfigBinding(key = "whois")
161
+    void handleWhois(final boolean value) {
162
+        whois = value;
163
+    }
164
+
165
+    @ConfigBinding(key = "autoinvite")
166
+    void handleAutoInvite(final boolean value) {
167
+        autoInvite = value;
168
+    }
169
+
170
+    @ConfigBinding(key = "acceptinvites")
171
+    void handleAcceptInvites(final boolean value) {
172
+        acceptInvites = value;
51 173
     }
52 174
 
53
-    public void showConfig(final ClientPrefsOpenedEvent event) {
54
-        // TODO: Show a config
175
+    @Handler
176
+    void showConfig(final ClientPrefsOpenedEvent event) {
177
+        final PluginPreferencesCategory category = new PluginPreferencesCategory(pluginInfo,
178
+                "Q Auth", "Q Authentication settings");
179
+        category.addSetting(new PreferencesSetting(PreferencesType.TEXT, new NotEmptyValidator(),
180
+                domain, "username", "Username", "Your Q username",
181
+                event.getModel().getConfigManager(), event.getModel().getIdentity()));
182
+        category.addSetting(new PreferencesSetting(PreferencesType.TEXT, new NotEmptyValidator(),
183
+                domain, "password", "Password", "Your Q password",
184
+                event.getModel().getConfigManager(), event.getModel().getIdentity()));
185
+        category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
186
+                domain, "whois", "Whois before auth",
187
+                "Should we send a whois before authing and only auth if required?",
188
+                event.getModel().getConfigManager(), event.getModel().getIdentity()));
189
+        category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
190
+                domain, "autoinvite", "Auto Invite", "Should Q autoinvite you to channels?",
191
+                event.getModel().getConfigManager(), event.getModel().getIdentity()));
192
+        category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
193
+                domain, "acceptinvites", "Auto Accept Invites",
194
+                "Should the client automatically accept invites from Q?",
195
+                event.getModel().getConfigManager(), event.getModel().getIdentity()));
196
+        event.getModel().getCategory("Plugins").addSubCategory(category);
55 197
     }
56 198
 }

+ 211
- 0
qauth/test/com/dmdirc/addons/qauth/QAuthManagerTest.java Целия файл

@@ -0,0 +1,211 @@
1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.qauth;
24
+
25
+import com.dmdirc.DMDircMBassador;
26
+import com.dmdirc.Invite;
27
+import com.dmdirc.Query;
28
+import com.dmdirc.config.ConfigBinder;
29
+import com.dmdirc.events.QueryMessageEvent;
30
+import com.dmdirc.events.ServerConnectedEvent;
31
+import com.dmdirc.events.ServerInviteReceivedEvent;
32
+import com.dmdirc.events.ServerNoticeEvent;
33
+import com.dmdirc.interfaces.Connection;
34
+import com.dmdirc.interfaces.User;
35
+import com.dmdirc.interfaces.config.AggregateConfigProvider;
36
+import com.dmdirc.plugins.PluginInfo;
37
+
38
+import java.util.Optional;
39
+
40
+import org.junit.Before;
41
+import org.junit.Test;
42
+import org.junit.runner.RunWith;
43
+import org.mockito.Mock;
44
+import org.mockito.runners.MockitoJUnitRunner;
45
+
46
+import static org.mockito.Matchers.anyString;
47
+import static org.mockito.Mockito.never;
48
+import static org.mockito.Mockito.verify;
49
+import static org.mockito.Mockito.verifyZeroInteractions;
50
+import static org.mockito.Mockito.when;
51
+
52
+@RunWith(MockitoJUnitRunner.class)
53
+public class QAuthManagerTest {
54
+
55
+    @Mock private DMDircMBassador eventBus;
56
+    @Mock private PluginInfo pluginInfo;
57
+    @Mock private AggregateConfigProvider config;
58
+    @Mock private ConfigBinder configBinder;
59
+    @Mock private ServerConnectedEvent serverConnectedEvent;
60
+    @Mock private ServerInviteReceivedEvent serverInviteReceivedEvent;
61
+    @Mock private ServerNoticeEvent serverNoticeEvent;
62
+    @Mock private QueryMessageEvent queryMessageEvent;
63
+    @Mock private User user;
64
+    @Mock private Query query;
65
+    @Mock private Invite invite;
66
+    @Mock private Connection connection;
67
+    private QAuthManager instance;
68
+
69
+    @Before
70
+    public void setUp() throws Exception {
71
+        when(serverConnectedEvent.getConnection()).thenReturn(connection);
72
+        when(serverInviteReceivedEvent.getConnection()).thenReturn(connection);
73
+        when(serverInviteReceivedEvent.getInvite()).thenReturn(invite);
74
+        when(serverInviteReceivedEvent.getChannel()).thenReturn("#channel");
75
+        when(serverInviteReceivedEvent.getUser()).thenReturn(user);
76
+        when(serverNoticeEvent.getConnection()).thenReturn(connection);
77
+        when(serverNoticeEvent.getUser()).thenReturn(user);
78
+        when(serverNoticeEvent.getMessage()).thenReturn("You are now logged in as username.");
79
+        when(queryMessageEvent.getQuery()).thenReturn(query);
80
+        when(queryMessageEvent.getUser()).thenReturn(user);
81
+        when(queryMessageEvent.getMessage()).thenReturn("You are now logged in as username.");
82
+        when(user.getNickname()).thenReturn("Q");
83
+        when(query.getConnection()).thenReturn(Optional.of(connection));
84
+        when(connection.getNetwork()).thenReturn("Quakenet");
85
+        when(config.getBinder()).thenReturn(configBinder);
86
+        when(configBinder.withDefaultDomain("pluginDomain")).thenReturn(configBinder);
87
+        instance = new QAuthManager("pluginDomain", pluginInfo, config, eventBus);
88
+
89
+        instance.handleUsername("username");
90
+        instance.handlePassword("password");
91
+        instance.handleAcceptInvites(true);
92
+        instance.handleAutoInvite(true);
93
+    }
94
+
95
+    @Test
96
+    public void testLoad() {
97
+        instance.load();
98
+        verify(configBinder).bind(instance, QAuthManager.class);
99
+        verify(eventBus).subscribe(instance);
100
+    }
101
+
102
+    @Test
103
+    public void testUnload() {
104
+        instance.unload();
105
+        verify(configBinder).unbind(instance);
106
+        verify(eventBus).unsubscribe(instance);
107
+    }
108
+
109
+    @Test
110
+    public void testConnected_IncorrectNetwork() {
111
+        when(connection.getNetwork()).thenReturn("NotQuakenet");
112
+        instance.handleConnect(serverConnectedEvent);
113
+        verify(connection, never()).sendMessage(anyString(), anyString());
114
+    }
115
+
116
+    @Test
117
+    public void testConnected_Quakenet() {
118
+        instance.handleConnect(serverConnectedEvent);
119
+        verify(connection).sendMessage("Q@Cserve.quakenet.org", "auth username password");
120
+    }
121
+
122
+    @Test
123
+    public void testInvites_NoHandle() {
124
+        instance.handleAcceptInvites(false);
125
+        instance.handleInvite(serverInviteReceivedEvent);
126
+        verifyZeroInteractions(invite);
127
+    }
128
+
129
+    @Test
130
+    public void testInvites_NotQuakenet() {
131
+        when(connection.getNetwork()).thenReturn("NotQuakenet");
132
+        instance.handleInvite(serverInviteReceivedEvent);
133
+        verifyZeroInteractions(invite);
134
+    }
135
+
136
+    @Test
137
+    public void testInvites_Quakenet_NotQ() {
138
+        when(user.getNickname()).thenReturn("NotQ");
139
+        instance.handleAcceptInvites(false);
140
+        instance.handleInvite(serverInviteReceivedEvent);
141
+        verifyZeroInteractions(invite);
142
+    }
143
+
144
+    @Test
145
+    public void testInvites_Quakenet_Q() {
146
+        instance.handleInvite(serverInviteReceivedEvent);
147
+        verify(invite).accept();
148
+    }
149
+
150
+    @Test
151
+    public void testCommunication_Message_NoConnection() {
152
+        when(queryMessageEvent.getQuery()).thenReturn(query);
153
+        when(query.getConnection()).thenReturn(Optional.<Connection>empty());
154
+        instance.handleMessages(queryMessageEvent);
155
+        verifyZeroInteractions(connection);
156
+    }
157
+
158
+    @Test
159
+    public void testCommunication_Message_NotQuakenet() {
160
+        when(connection.getNetwork()).thenReturn("NotQuakenet");
161
+        instance.handleMessages(queryMessageEvent);
162
+        verify(connection, never()).sendMessage(anyString(), anyString());
163
+    }
164
+
165
+    @Test
166
+    public void testCommunication_Message_Quakenet_NotQ() {
167
+        when(user.getNickname()).thenReturn("NotQ");
168
+        instance.handleMessages(queryMessageEvent);
169
+        verify(connection, never()).sendMessage(anyString(), anyString());
170
+    }
171
+
172
+    @Test
173
+    public void testCommunication_Message_Quakenet_Q() {
174
+        instance.handleMessages(queryMessageEvent);
175
+        verify(connection).sendMessage("Q@Cserve.quakenet.org", "invite");
176
+    }
177
+
178
+    @Test
179
+    public void testCommunication_Message_Off() {
180
+        instance.handleAutoInvite(false);
181
+        instance.handleMessages(queryMessageEvent);
182
+        verify(connection, never()).sendMessage("Q@Cserve.quakenet.org", "invite");
183
+    }
184
+
185
+    @Test
186
+    public void testCommunication_Notice_NotQuakenet() {
187
+        when(connection.getNetwork()).thenReturn("NotQuakenet");
188
+        instance.handleNotices(serverNoticeEvent);
189
+        verify(connection, never()).sendMessage(anyString(), anyString());
190
+    }
191
+
192
+    @Test
193
+    public void testCommunication_Notice_Quakenet_NotQ() {
194
+        when(user.getNickname()).thenReturn("NotQ");
195
+        instance.handleNotices(serverNoticeEvent);
196
+        verify(connection, never()).sendMessage(anyString(), anyString());
197
+    }
198
+
199
+    @Test
200
+    public void testCommunication_Notice_Quakenet_Q() {
201
+        instance.handleNotices(serverNoticeEvent);
202
+        verify(connection).sendMessage("Q@Cserve.quakenet.org", "invite");
203
+    }
204
+
205
+    @Test
206
+    public void testCommunication_Notice_Off() {
207
+        instance.handleAutoInvite(false);
208
+        instance.handleNotices(serverNoticeEvent);
209
+        verify(connection, never()).sendMessage("Q@Cserve.quakenet.org", "invite");
210
+    }
211
+}

Loading…
Отказ
Запис