diff --git a/pom.xml b/pom.xml
index 4338272..1003ff6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,10 @@
tmortagne
Thomas Mortagne
+
+ martindelille
+ Martin Delille
+
usersync-api
@@ -85,4 +89,21 @@
+
+
+ com.squareup.retrofit2
+ retrofit
+ 2.5.0
+
+
+ com.squareup.retrofit2
+ converter-gson
+ 2.5.0
+
+
+ com.squareup.okhttp3
+ logging-interceptor
+ 3.12.0
+
+
diff --git a/usersync-api/src/main/java/org/xwiki/contrib/usersync/UserSyncConnector.java b/usersync-api/src/main/java/org/xwiki/contrib/usersync/UserSyncConnector.java
index cb1d0b2..8737580 100644
--- a/usersync-api/src/main/java/org/xwiki/contrib/usersync/UserSyncConnector.java
+++ b/usersync-api/src/main/java/org/xwiki/contrib/usersync/UserSyncConnector.java
@@ -34,16 +34,16 @@ public interface UserSyncConnector
/**
* @param user the object containing the metadata of the new user
*/
- void createUser(BaseObject user);
+ void createUser(BaseObject user) throws UserSyncException;
/**
* @param previousUser the object containing the previous metadata of the user
* @param previousUser the object containing the new metadata of the user
*/
- void modifyUser(BaseObject previousUser, BaseObject newUser);
+ void modifyUser(BaseObject previousUser, BaseObject newUser) throws UserSyncException;
/**
* @param deletedUser the object containing the metadata of the deleted user
*/
- void deleteUser(BaseObject deletedUser);
+ void deleteUser(BaseObject deletedUser) throws UserSyncException;
}
diff --git a/usersync-api/src/main/java/org/xwiki/contrib/usersync/interval/UserSyncListener.java b/usersync-api/src/main/java/org/xwiki/contrib/usersync/interval/UserSyncListener.java
index b9d2ecb..8ba9b1c 100644
--- a/usersync-api/src/main/java/org/xwiki/contrib/usersync/interval/UserSyncListener.java
+++ b/usersync-api/src/main/java/org/xwiki/contrib/usersync/interval/UserSyncListener.java
@@ -27,6 +27,7 @@
import org.xwiki.component.annotation.Component;
import org.xwiki.contrib.usersync.UserSyncConnector;
+import org.xwiki.contrib.usersync.UserSyncException;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.observation.AbstractEventListener;
import org.xwiki.observation.event.Event;
@@ -80,12 +81,16 @@ private void onEvent(UserSyncConnector connector, XObjectEvent event, XWikiDocum
BaseObject newUser = document.getXObject(event.getReference());
BaseObject previousUser = document.getOriginalDocument().getXObject(event.getReference());
- if (event instanceof XObjectAddedEvent) {
- connector.createUser(newUser);
- } else if (event instanceof XObjectDeletedEvent) {
- connector.deleteUser(previousUser);
- } else {
- connector.modifyUser(previousUser, newUser);
+ try {
+ if (event instanceof XObjectAddedEvent) {
+ connector.createUser(newUser);
+ } else if (event instanceof XObjectDeletedEvent) {
+ connector.deleteUser(previousUser);
+ } else {
+ connector.modifyUser(previousUser, newUser);
+ }
+ } catch (UserSyncException exception) {
+ System.out.println(exception.getMessage());
}
}
}
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/CreateUserBody.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/CreateUserBody.java
new file mode 100644
index 0000000..26393ab
--- /dev/null
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/CreateUserBody.java
@@ -0,0 +1,23 @@
+package org.xwiki.contrib.usersync.discourse.internal;
+
+import com.google.gson.annotations.SerializedName;
+
+public class CreateUserBody {
+ private String username;
+
+ private String name;
+
+ private String email;
+
+ private String password;
+
+ private Boolean active;
+
+ public CreateUserBody(String _username, String _name, String _email, String _password) {
+ username = _username;
+ name = _name;
+ email = _email;
+ password = _password;
+ active = true;
+ }
+}
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/CreateUserResponse.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/CreateUserResponse.java
new file mode 100644
index 0000000..b6f16aa
--- /dev/null
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/CreateUserResponse.java
@@ -0,0 +1,21 @@
+package org.xwiki.contrib.usersync.discourse.internal;
+
+import org.xwiki.contrib.usersync.discourse.internal.User;
+
+public class CreateUserResponse {
+ private Boolean success;
+
+ private String message;
+
+ private Integer user_id;
+
+ public Boolean getSuccess() {
+ return success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Integer getUserId() { return user_id; }
+}
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DeleteUserResponse.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DeleteUserResponse.java
new file mode 100644
index 0000000..0eda85d
--- /dev/null
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DeleteUserResponse.java
@@ -0,0 +1,11 @@
+package org.xwiki.contrib.usersync.discourse.internal;
+
+import org.xwiki.contrib.usersync.discourse.internal.User;
+
+public class DeleteUserResponse {
+ private Boolean deleted;
+
+ public Boolean getDeleted() {
+ return deleted;
+ }
+}
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseService.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseService.java
new file mode 100644
index 0000000..803212b
--- /dev/null
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseService.java
@@ -0,0 +1,21 @@
+package org.xwiki.contrib.usersync.discourse.internal;
+
+import retrofit2.Call;
+import retrofit2.http.Body;
+import retrofit2.http.DELETE;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+import retrofit2.http.Header;
+
+public interface DiscourseService {
+ @GET("users/{username}.json")
+ Call getUser(@Path("username") String username, @Header("Api-Key") String apiKey, @Header("Api-Username") String apiUsername);
+
+ @POST("users")
+ Call createUser(@Body CreateUserBody createUserBody, @Header("Api-Key") String apiKey, @Header("Api-Username") String apiUsername);
+
+ @DELETE("/admin/users/{userid}.json")
+ Call deleteUser(@Path("userid") Integer userId, @Header("Api-Key") String apiKey, @Header("Api-Username") String apiUsername);
+}
+
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnector.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnector.java
index 13ff277..7041c10 100644
--- a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnector.java
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnector.java
@@ -19,57 +19,164 @@
*/
package org.xwiki.contrib.usersync.discourse.internal;
+import java.io.IOException;
+
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.xwiki.component.annotation.Component;
+import org.xwiki.component.phase.Initializable;
+import org.xwiki.component.phase.InitializationException;
import org.xwiki.configuration.ConfigurationSource;
import org.xwiki.contrib.usersync.UserSyncConnector;
+import org.xwiki.contrib.usersync.UserSyncException;
import com.xpn.xwiki.objects.BaseObject;
+import okhttp3.OkHttpClient;
+import okhttp3.logging.HttpLoggingInterceptor;
+import retrofit2.Call;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
/**
* {@link UserSyncConnector} implementation for Discourse.
- *
+ *
* @version $Id$
*/
@Component
@Singleton
@Named("discourse")
-public class DiscourseUserSyncConnector implements UserSyncConnector
+public class DiscourseUserSyncConnector implements UserSyncConnector, Initializable
{
private static final String PREFIX_CONFIGURATION = "usersync.discourse.";
-
- private static final String CONFIGURATION_URL = PREFIX_CONFIGURATION + "url";
+
+ public static final String CONFIGURATION_URL = PREFIX_CONFIGURATION + "url";
+ public static final String CONFIGURATION_API_KEY = PREFIX_CONFIGURATION + "api_key";
+ public static final String CONFIGURATION_API_USERNAME = PREFIX_CONFIGURATION + "api_username";
@Inject
private ConfigurationSource configuration;
+ HttpLoggingInterceptor logging;
+ OkHttpClient.Builder httpClient;
+
+ private Retrofit retrofit;
+ private DiscourseService service;
+ String discourseURL;
+ String discourseApiKey;
+ String discourseApiUsername;
+
@Override
- public void createUser(BaseObject user)
+ public void initialize() throws InitializationException
{
+ // Get the URL of the discourse server to synchronize with
+ discourseURL = this.configuration.getProperty(CONFIGURATION_URL);
+ discourseApiKey = this.configuration.getProperty(CONFIGURATION_API_KEY);
+ discourseApiUsername = this.configuration.getProperty(CONFIGURATION_API_USERNAME);
+
+ logging = new HttpLoggingInterceptor();
+ logging.setLevel(HttpLoggingInterceptor.Level.BODY);
+ httpClient = new OkHttpClient.Builder();
+ httpClient.addInterceptor(logging);
+
+ retrofit = new Retrofit.Builder()
+ .baseUrl(discourseURL)
+ .addConverterFactory(GsonConverterFactory.create())
+ .client(httpClient.build())
+ .build();
+
+ service = retrofit.create(DiscourseService.class);
+ }
+
+ @Override
+ public void createUser(BaseObject userObject) throws UserSyncException {
// Get the user login
- String userId = user.getReference().getName();
+ String userId = userObject.getStringValue("id");
- // Get the user mail
- String mail = user.getStringValue("email");
+ // Get the user email
+ String email = userObject.getStringValue("email");
- // Get the URL of the discourse server to synchronize with
- String discourseURL = this.configuration.getProperty(CONFIGURATION_URL);
+ // Get the user password
+ String password = userObject.getStringValue("password");
- // TODO
+ // Get the user name
+ String name = userObject.getStringValue("name");
+
+ System.out.printf("creating user: %s / %s / %s / %s\n", userId, email, password, name);
+
+ CreateUserBody createUserBody = new CreateUserBody(userId, name, email, password);
+
+ Call call = service.createUser(createUserBody, discourseApiKey, discourseApiUsername);
+
+ try {
+ Response response = call.execute();
+ if(response.isSuccessful()) {
+ System.out.println("succeed!");
+ CreateUserResponse createUserResponse = response.body();
+ if (createUserResponse.getSuccess()) {
+ System.out.println("Success creating user with id:" + createUserResponse.getUserId());
+ userObject.setIntValue("id", createUserResponse.getUserId());
+ } else {
+ throw new UserSyncException(createUserResponse.getMessage());
+ }
+ } else {
+ System.out.println("Code: " + response.code());
+ throw new UserSyncException("Bad response code:" + response.code());
+ }
+ } catch (IOException exception) {
+ System.out.println(exception.getMessage());
+ throw new UserSyncException("Unknown error", exception);
+ }
}
@Override
- public void modifyUser(BaseObject previousUser, BaseObject newUser)
+ public void modifyUser(BaseObject previousUser, BaseObject newUser) throws UserSyncException
{
// TODO
}
@Override
- public void deleteUser(BaseObject deletedUser)
+ public void deleteUser(BaseObject userObject) throws UserSyncException
{
- // TODO
+ // Get the user login
+ String userName = userObject.getStringValue("id");
+
+ System.out.printf("deleting user: %s\n", userName);
+
+ Call getUserResponseCall = service.getUser(userName, discourseApiKey, discourseApiUsername);
+
+
+
+ try {
+ Response getUserResponse = getUserResponseCall.execute();
+ if (getUserResponse.isSuccessful()) {
+ System.out.printf("user name is " + getUserResponse.body().getUser().getEmail());
+ Integer userId = getUserResponse.body().getUser().getId();
+ System.out.printf("user id is " + userId);
+ Call deleteUserResponseCall = service.deleteUser(userId, discourseApiKey, discourseApiUsername);
+
+ Response deleteUserResponse = deleteUserResponseCall.execute();
+ if(deleteUserResponse.isSuccessful()) {
+ System.out.println("succeed!");
+ if (deleteUserResponse.body().getDeleted()) {
+ System.out.println("Success deleting user");
+ } else {
+ throw new UserSyncException("Failed deleting user");
+ }
+ } else {
+ System.out.println("Code: " + deleteUserResponse.code());
+ throw new UserSyncException("Bad response code for deleteUser:" + deleteUserResponse.code());
+ }
+ } else {
+ System.out.println("Code: " + getUserResponse.code());
+ throw new UserSyncException("Bad response code for getUser:" + getUserResponse.code());
+ }
+ } catch (IOException exception) {
+ System.out.println(exception.getMessage());
+ throw new UserSyncException("Unknown error", exception);
+ }
}
}
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/GetUserResponse.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/GetUserResponse.java
new file mode 100644
index 0000000..cfad7ea
--- /dev/null
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/GetUserResponse.java
@@ -0,0 +1,11 @@
+package org.xwiki.contrib.usersync.discourse.internal;
+
+import org.xwiki.contrib.usersync.discourse.internal.User;
+
+public class GetUserResponse {
+ private User user;
+
+ public User getUser() {
+ return user;
+ }
+}
diff --git a/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/User.java b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/User.java
new file mode 100644
index 0000000..6cbe3c8
--- /dev/null
+++ b/usersync-connectors/usersync-connector-discourse/src/main/java/org/xwiki/contrib/usersync/discourse/internal/User.java
@@ -0,0 +1,33 @@
+package org.xwiki.contrib.usersync.discourse.internal;
+
+import com.google.gson.annotations.SerializedName;
+
+public class User {
+ private int id;
+
+ private String username;
+
+ private String name;
+
+ private String email;
+
+ private String password;
+
+ public int getId() { return id; }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+}
diff --git a/usersync-connectors/usersync-connector-discourse/src/test/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnectorTest.java b/usersync-connectors/usersync-connector-discourse/src/test/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnectorTest.java
index 079eebe..9a0093f 100644
--- a/usersync-connectors/usersync-connector-discourse/src/test/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnectorTest.java
+++ b/usersync-connectors/usersync-connector-discourse/src/test/java/org/xwiki/contrib/usersync/discourse/internal/DiscourseUserSyncConnectorTest.java
@@ -19,13 +19,17 @@
*/
package org.xwiki.contrib.usersync.discourse.internal;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.xwiki.component.manager.ComponentLookupException;
+import org.xwiki.configuration.internal.MemoryConfigurationSource;
import org.xwiki.contrib.usersync.UserSyncConnector;
+import org.xwiki.contrib.usersync.UserSyncException;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.LocalDocumentReference;
+import org.xwiki.test.annotation.AfterComponent;
import org.xwiki.test.mockito.MockitoComponentMockingRule;
import com.xpn.xwiki.doc.XWikiDocument;
@@ -48,6 +52,12 @@ public class DiscourseUserSyncConnectorTest
private BaseObject newUser;
private BaseObject previousUser;
+ private MemoryConfigurationSource configuration = oldcore.getConfigurationSource();
+
+ @AfterComponent
+ public void afterComponent() throws Exception {
+ configuration = mocker.registerMemoryConfigurationSource();
+ }
@Before
public void before()
@@ -57,7 +67,10 @@ public void before()
this.newUser = new BaseObject();
this.newUser.setXClassReference(new LocalDocumentReference("XWiki", "XWikiUsers"));
- this.newUser.setStringValue("email", "mail@domain.com");
+ this.newUser.setStringValue("id", "SergeGainsbourg");
+ this.newUser.setStringValue("email", "martin@phonations.com");
+ this.newUser.setStringValue("password", "abcdefgh1234");
+ this.newUser.setStringValue("name", "Serge Gainsbourg");
userDocument.addXObject(this.newUser);
@@ -67,14 +80,37 @@ public void before()
}
@Test
+ public void createUser() throws ComponentLookupException
+ {
+ try {
+ // Call the component
+ this.mocker.getComponentUnderTest().createUser(this.newUser);
+ } catch (UserSyncException exception) {
+ Assert.fail(exception.getMessage());
+ }
+ }
+
public void modifyUser() throws ComponentLookupException
{
// Modify the user
this.newUser.setStringValue("email", "differentmail@domain.com");
- // Call the component
- this.mocker.getComponentUnderTest().modifyUser(this.previousUser, this.newUser);
+ try {
+ // Call the component
+ this.mocker.getComponentUnderTest().modifyUser(this.previousUser, this.newUser);
+ } catch (UserSyncException exception) {
+ Assert.fail(exception.getMessage());
+ }
+ }
- // TODO
+ @Test
+ public void deleteUser() throws ComponentLookupException
+ {
+ try {
+ // Call the component
+ this.mocker.getComponentUnderTest().deleteUser(this.newUser);
+ } catch (UserSyncException exception) {
+ Assert.fail(exception.getMessage());
+ }
}
}