diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.desc.xml
new file mode 100644
index 0000000000..e139449d80
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.desc.xml
@@ -0,0 +1,8 @@
+
+ Membership
+ Get the membership details for a user
+ /api/sites/{shortname}/memberships/{username}
+
+ guest
+ required
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.js
new file mode 100644
index 0000000000..3009123d78
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.js
@@ -0,0 +1,21 @@
+function main()
+{
+ // Get the url values
+ var urlElements = url.extension.split("/");
+ var shortName = urlElements[0];
+ var userName = urlElements[2];
+
+ // Get the site
+ var site = siteService.getSite(shortName);
+ if (site == null)
+ {
+ // Site cannot be found
+ status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist.");
+ return;
+ }
+
+ // Remove the user from the site
+ site.removeMembership(userName);
+}
+
+main();
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.delete.json.ftl
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.desc.xml
new file mode 100644
index 0000000000..e139449d80
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.desc.xml
@@ -0,0 +1,8 @@
+
+ Membership
+ Get the membership details for a user
+ /api/sites/{shortname}/memberships/{username}
+
+ guest
+ required
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.js
new file mode 100644
index 0000000000..46028a8879
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.js
@@ -0,0 +1,41 @@
+function main()
+{
+ // Get the url values
+ var urlElements = url.extension.split("/");
+ var shortName = urlElements[0];
+ var userName = urlElements[2];
+
+ // Get the site
+ var site = siteService.getSite(shortName);
+ if (site == null)
+ {
+ // Site cannot be found
+ status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist.");
+ return;
+ }
+
+ var person = people.getPerson(userName);
+ if (person == null)
+ {
+ // Person cannot be found
+ status.setCode(status.STATUS_NOT_FOUND, "The person with user name " + userName + " does not exist.");
+ return;
+ }
+
+ // Get the role of the user
+ var role = site.getMembersRole(userName);
+ if (role == null)
+ {
+ // Person is not a member of the site
+ status.setCode(status.STATUS_NOT_FOUND, "The person with user name " + userName + " is not a member of the site " + shortName);
+ return;
+ }
+
+ // Pass the values to the template
+ model.site = site;
+ model.person = person;
+ model.role = role;
+}
+
+main();
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.json.ftl
new file mode 100644
index 0000000000..fdf2fe5dfd
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.get.json.ftl
@@ -0,0 +1,2 @@
+<#import "membership.lib.ftl" as membershipLib/>
+<@membershipLib.membershipJSON site=site role=role person=person/>
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.desc.xml
new file mode 100644
index 0000000000..e139449d80
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.desc.xml
@@ -0,0 +1,8 @@
+
+ Membership
+ Get the membership details for a user
+ /api/sites/{shortname}/memberships/{username}
+
+ guest
+ required
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.js
new file mode 100644
index 0000000000..dd27af8f08
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.js
@@ -0,0 +1,44 @@
+function main()
+{
+ // Get the site
+ var shortName = url.extension.split("/")[0];
+ var site = siteService.getSite(shortName);
+ if (site == null)
+ {
+ // Site cannot be found
+ status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist.");
+ return;
+ }
+
+ // Get the role
+ var role = json.get("role");
+ if (role == null)
+ {
+ status.setCode(status.STATUS_BAD_REQUEST, "The role has not been set.");
+ return;
+ }
+
+ // Get the user name
+ var userName = json.getJSONObject("person").get("userName");
+ if (userName == null)
+ {
+ status.setCode(status.STATUS_BAD_REQUEST, "The user name has not been set.");
+ return;
+ }
+ var person = people.getPerson(userName);
+ if (person == null)
+ {
+ status.setCode(status.STATUS_BAD_REQUEST, "The person with user name " + userName + " could not be found.");
+ return;
+ }
+
+ // Set the membership details
+ site.setMembership(userName, role);
+
+ // Pass the details to the template
+ model.site = site;
+ model.role = role;
+ model.person = person;
+}
+
+main();
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.json.ftl
new file mode 100644
index 0000000000..fdf2fe5dfd
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/membership.put.json.ftl
@@ -0,0 +1,2 @@
+<#import "membership.lib.ftl" as membershipLib/>
+<@membershipLib.membershipJSON site=site role=role person=person/>
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/memberships.post.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/memberships.post.js
index 4d8803d28e..dd27af8f08 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/memberships.post.js
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/membership/memberships.post.js
@@ -1,15 +1,44 @@
-// Get the site
-var shortName = url.extension.split("/")[0];
-var site = siteService.getSite(shortName);
+function main()
+{
+ // Get the site
+ var shortName = url.extension.split("/")[0];
+ var site = siteService.getSite(shortName);
+ if (site == null)
+ {
+ // Site cannot be found
+ status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist.");
+ return;
+ }
+
+ // Get the role
+ var role = json.get("role");
+ if (role == null)
+ {
+ status.setCode(status.STATUS_BAD_REQUEST, "The role has not been set.");
+ return;
+ }
+
+ // Get the user name
+ var userName = json.getJSONObject("person").get("userName");
+ if (userName == null)
+ {
+ status.setCode(status.STATUS_BAD_REQUEST, "The user name has not been set.");
+ return;
+ }
+ var person = people.getPerson(userName);
+ if (person == null)
+ {
+ status.setCode(status.STATUS_BAD_REQUEST, "The person with user name " + userName + " could not be found.");
+ return;
+ }
+
+ // Set the membership details
+ site.setMembership(userName, role);
+
+ // Pass the details to the template
+ model.site = site;
+ model.role = role;
+ model.person = person;
+}
-// Get the role
-var role = json.get("role");
-var userName = json.getJSONObject("person").get("userName");
-
-// Set the membership details
-site.setMembership(userName, role);
-
-// Pass the details to the template
-model.site = site;
-model.role = role;
-model.person = people.getPerson(userName);
\ No newline at end of file
+main();
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java b/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java
index fc7cd89828..eb14ed7587 100644
--- a/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java
+++ b/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java
@@ -251,4 +251,83 @@ public class SiteServiceTest extends BaseWebScriptTest
assertNotNull(result2);
assertEquals(2, result2.length());
}
+
+ public void testGetMembership() throws Exception
+ {
+ // Create a site
+ String shortName = GUID.generate();
+ createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
+
+ // Test error conditions
+ getRequest(URL_SITES + "/badsite" + URL_MEMBERSHIPS + "/" + USER_ONE, 404);
+ getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/baduser", 404);
+ getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_TWO, 404);
+
+ MockHttpServletResponse response = getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_ONE, 200);
+ JSONObject result = new JSONObject(response.getContentAsString());
+
+ // Check the result
+ assertEquals(SiteModel.SITE_MANAGER, result.get("role"));
+ assertEquals(USER_ONE, result.getJSONObject("person").get("userName"));
+ }
+
+ public void testPutMembership() throws Exception
+ {
+ // Create a site
+ String shortName = GUID.generate();
+ createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
+
+ // Test error conditions
+ // TODO
+
+ // Build the JSON membership object
+ JSONObject membership = new JSONObject();
+ membership.put("role", SiteModel.SITE_CONSUMER);
+ JSONObject person = new JSONObject();
+ person.put("userName", USER_TWO);
+ membership.put("person", person);
+
+ // Post the memebership
+ MockHttpServletResponse response = postRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS, 200, membership.toString(), "application/json");
+ JSONObject newMember = new JSONObject(response.getContentAsString());
+
+ // Update the role
+ newMember.put("role", SiteModel.SITE_COLLABORATOR);
+ response = putRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_TWO, 200, newMember.toString(), "application/json");
+ JSONObject result = new JSONObject(response.getContentAsString());
+
+ // Check the result
+ assertEquals(SiteModel.SITE_COLLABORATOR, result.get("role"));
+ assertEquals(USER_TWO, result.getJSONObject("person").get("userName"));
+
+ // Double check and get the membership for user two
+ response = getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_TWO, 200);
+ result = new JSONObject(response.getContentAsString());
+ assertEquals(SiteModel.SITE_COLLABORATOR, result.get("role"));
+ assertEquals(USER_TWO, result.getJSONObject("person").get("userName"));
+ }
+
+ public void testDeleteMembership() throws Exception
+ {
+ // Create a site
+ String shortName = GUID.generate();
+ createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
+
+ // Build the JSON membership object
+ JSONObject membership = new JSONObject();
+ membership.put("role", SiteModel.SITE_CONSUMER);
+ JSONObject person = new JSONObject();
+ person.put("userName", USER_TWO);
+ membership.put("person", person);
+
+ // Post the membership
+ postRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS, 200, membership.toString(), "application/json");
+
+ // Delete the membership
+ deleteRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_TWO, 200);
+
+ // Check that the membership has been deleted
+ getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_TWO, 404);
+
+ }
}