diff --git a/changelog.html b/changelog.html index 82d83c4b4..8a463878d 100644 --- a/changelog.html +++ b/changelog.html @@ -47,6 +47,7 @@

1.12.1 (to be determined)

-
  • (Deprecated) User Service Plugin Readme - -
  • @@ -2853,101 +2843,6 @@

    ClusterNode

    Affiliation of the user -

    (Deprecated) User Service Plugin Readme

    -

    Overview

    -

    The User Service Plugin provides the ability to add,edit,delete users and manage their rosters by sending an http request to the server. It is intended to be used by applications automating the user administration process. This plugin’s functionality is useful for applications that need to administer users outside of the Openfire admin console. An example of such an application might be a live sports reporting application that uses XMPP as its transport, and creates/deletes users according to the receipt, or non receipt, of a subscription fee.

    -

    Installation

    -

    Copy userservice.jar into the plugins directory of your Openfire server. The plugin will then be automatically deployed. To upgrade to a new version, copy the new userservice.jar file over the existing file.

    -

    Configuration

    -

    Access to the service is restricted with a “secret” that can be viewed and set from the User Service page in the Openfire admin console. This page is located on the admin console under “Server” and then “Server Settings”. This should really only be considered weak security. The plugin was initially written with the assumption that http access to the Openfire service was only available to trusted machines. In the case of the plugin’s author, a web application running on the same server as Openfire makes the request.

    -

    Using the Plugin

    -

    To administer users, submit HTTP requests to the userservice service. The service address is [hostname]plugins/restapi/userservice. For example, if your server name is “example.com”, the URL is http://example.com/plugins/restapi/userservice

    -

    The following parameters can be passed into the request:

    -

    | Name | | Description | |--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    - | type | Required | The admin service required. Possible values are ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’, ‘grouplist’, ‘usergrouplist’. |
    - | secret | Required | The secret key that allows access to the User Service. |
    - | username | Required | The username of the user to ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’. ie the part before the @ symbol. |
    - | password | Required for ‘add’ operation | The password of the new user or the user being updated. |
    - | name | Optional | The display name of the new user or the user being updated. For ‘add_roster’, ‘update_roster’ operations specifies the nickname of the roster item. |
    - | email | Optional | The email address of the new user or the user being updated. |
    - | groups | Optional | List of groups where the user is a member. Values are comma delimited. When used with types “add” or “update”, it adds the user to shared groups and auto-creates new groups. When used with ‘add_roster’ and ‘update_roster’, it adds the user to roster groups provided the group name does not clash with an existing shared group. |
    - | item_jid | Required for ‘add_roster’, ‘update_roster’, ‘delete_roster’ operations. | The JID of the roster item |
    - | subscription | Optional | Type of subscription for ‘add_roster’, ‘update_roster’ operations. Possible numeric values are: -1(remove), 0(none), 1(to), 2(from), 3(both). |

    -

    Sample HTML

    -

    The following example adds a user

    -

    http://example.com:9090/plugins/restapi/userservice?type=add&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=franz@kafka.com

    -

    The following example adds a user, adds two shared groups (if not existing) and adds the user to both groups.

    -

    http://example.com:9090/plugins/restapi/userservice?type=add&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=franz@kafka.com&groups=support,finance

    -

    The following example deletes a user and all roster items of the user.

    -

    http://example.com:9090/plugins/restapi/userservice?type=delete&secret=bigsecret&username=kafka

    -

    The following example disables a user (lockout)

    -

    http://example.com:9090/plugins/restapi/userservice?type=disable&secret=bigsecret&username=kafka

    -

    The following example enables a user (removes lockout)

    -

    http://example.com:9090/plugins/restapi/userservice?type=enable&secret=bigsecret&username=kafka

    -

    The following example updates a user

    -

    http://example.com:9090/plugins/restapi/userservice?type=update&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=beetle@kafka.com

    -

    The following example adds new roster item with subscription ‘both’ for user ‘kafka’

    -

    http://example.com:9090/plugins/restapi/userservice?type=add_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com&name=franz&subscription=3

    -

    The following example adds new roster item with subscription ‘both’ for user ‘kafka’ and adds kafka to roster groups ‘family’ and ‘friends’

    -

    http://example.com:9090/plugins/restapi/userservice?type=add_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com&name=franz&subscription=3&groups=family,friends

    -

    The following example updates existing roster item to subscription ‘none’ for user ‘kafka’

    -

    http://example.com:9090/plugins/restapi/userservice?type=update_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com&name=franz&subscription=0

    -

    The following example deletes a specific roster item ‘franz@kafka.com’ for user ‘kafka’

    -

    http://example.com:9090/plugins/restapi/userservice?type=delete_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com

    -

    The following example gets all groups

    -

    http://example.com:9090/plugins/restapi/userservice?type=grouplist&secret=bigsecret
    - Which replies an XML group list formatted like this:

    -
    <result>
    - <groupname>group1</groupname> <groupname>group2</groupname></result>  
    -
    -

    The following example gets all groups for a specific user

    -

    http://example.com:9090/plugins/restapi/userservice?type=usergrouplist&secret=bigsecret&username=kafka
    - Which replies an XML group list formatted like this:

    -
    <result>
    - <groupname>usergroup1</groupname> <groupname>usergroup2</groupname></result>  
    -
    -

    When sending double characters (Chinese/Japanese/Korean etc.) you should URLEncode the string as utf8.
    - In Java this is done like this

    -
    -

    URLEncoder.encode(username, “UTF-8”));

    -
    -

    If the strings are encoded incorrectly, double byte characters will look garbeled in the Admin Console.

    -

    Server Reply

    -

    The server will reply to all User Service requests with an XML result page. If the request was processed successfully the return will be a “result” element with a text body of “OK”, or an XML grouplist formatted like in the example for “grouplist” and “usergrouplist” above. If the request was unsuccessful, the return will be an “error” element with a text body of one of the following error strings.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Error StringDescription
    IllegalArgumentExceptionOne of the parameters passed in to the User Service was bad.
    UserNotFoundExceptionNo user of the name specified, for a delete or update operation, exists on this server. For ‘update_roster’ operation, roster item to be updated was not found.
    UserAlreadyExistsExceptionA user with the same name as the user about to be added, already exists. For ‘add_roster’ operation, roster item with the same JID already exists.
    RequestNotAuthorisedThe supplied secret does not match the secret specified in the Admin Console or the requester is not a valid IP address.
    UserServiceDisabledThe User Service is currently set to disabled in the Admin Console.
    SharedGroupExceptionRoster item can not be added/deleted to/from a shared group for operations with roster.
    diff --git a/readme.md b/readme.md index 111c96c38..bacf218d7 100644 --- a/readme.md +++ b/readme.md @@ -2230,118 +2230,3 @@ If you want to create a resource with JSON data format, please add "**Content-Ty | userAddress | No | The JID of the user | | role | No | Role of the user | | affiliation | No | Affiliation of the user | - -# (Deprecated) User Service Plugin Readme - -## Overview - -The User Service Plugin provides the ability to add,edit,delete users and manage their rosters by sending an http request to the server. It is intended to be used by applications automating the user administration process. This plugin's functionality is useful for applications that need to administer users outside of the Openfire admin console. An example of such an application might be a live sports reporting application that uses XMPP as its transport, and creates/deletes users according to the receipt, or non receipt, of a subscription fee. - -## Installation - -Copy userservice.jar into the plugins directory of your Openfire server. The plugin will then be automatically deployed. To upgrade to a new version, copy the new userservice.jar file over the existing file. - -## Configuration - -Access to the service is restricted with a "secret" that can be viewed and set from the User Service page in the Openfire admin console. This page is located on the admin console under "Server" and then "Server Settings". This should really only be considered weak security. The plugin was initially written with the assumption that http access to the Openfire service was only available to trusted machines. In the case of the plugin's author, a web application running on the same server as Openfire makes the request. - -## Using the Plugin - -To administer users, submit HTTP requests to the userservice service. The service address is [hostname]plugins/restapi/userservice. For example, if your server name is "example.com", the URL is http://example.com/plugins/restapi/userservice - -The following parameters can be passed into the request: - -| Name | | Description | -|--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| type | Required | The admin service required. Possible values are 'add', 'delete', 'update', 'enable', 'disable', 'add_roster', 'update_roster', 'delete_roster', 'grouplist', 'usergrouplist'. | -| secret | Required | The secret key that allows access to the User Service. | -| username | Required | The username of the user to 'add', 'delete', 'update', 'enable', 'disable', 'add_roster', 'update_roster', 'delete_roster'. ie the part before the @ symbol. | -| password | Required for 'add' operation | The password of the new user or the user being updated. | -| name | Optional | The display name of the new user or the user being updated. For 'add_roster', 'update_roster' operations specifies the nickname of the roster item. | -| email | Optional | The email address of the new user or the user being updated. | -| groups | Optional | List of groups where the user is a member. Values are comma delimited. When used with types "add" or "update", it adds the user to shared groups and auto-creates new groups. When used with 'add_roster' and 'update_roster', it adds the user to roster groups provided the group name does not clash with an existing shared group. | -| item_jid | Required for 'add_roster', 'update_roster', 'delete_roster' operations. | The JID of the roster item | -| subscription | Optional | Type of subscription for 'add_roster', 'update_roster' operations. Possible numeric values are: -1(remove), 0(none), 1(to), 2(from), 3(both). | - -## Sample HTML -The following example adds a user - -http://example.com:9090/plugins/restapi/userservice?type=add&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=franz@kafka.com - -The following example adds a user, adds two shared groups (if not existing) and adds the user to both groups. - -http://example.com:9090/plugins/restapi/userservice?type=add&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=franz@kafka.com&groups=support,finance - -The following example deletes a user and all roster items of the user. - -http://example.com:9090/plugins/restapi/userservice?type=delete&secret=bigsecret&username=kafka - -The following example disables a user (lockout) - -http://example.com:9090/plugins/restapi/userservice?type=disable&secret=bigsecret&username=kafka - -The following example enables a user (removes lockout) - -http://example.com:9090/plugins/restapi/userservice?type=enable&secret=bigsecret&username=kafka - -The following example updates a user - -http://example.com:9090/plugins/restapi/userservice?type=update&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=beetle@kafka.com - -The following example adds new roster item with subscription 'both' for user 'kafka' - -http://example.com:9090/plugins/restapi/userservice?type=add_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com&name=franz&subscription=3 - -The following example adds new roster item with subscription 'both' for user 'kafka' and adds kafka to roster groups 'family' and 'friends' - -http://example.com:9090/plugins/restapi/userservice?type=add_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com&name=franz&subscription=3&groups=family,friends - -The following example updates existing roster item to subscription 'none' for user 'kafka' - -http://example.com:9090/plugins/restapi/userservice?type=update_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com&name=franz&subscription=0 - -The following example deletes a specific roster item 'franz@kafka.com' for user 'kafka' - -http://example.com:9090/plugins/restapi/userservice?type=delete_roster&secret=bigsecret&username=kafka&item_jid=franz@example.com - -The following example gets all groups - -http://example.com:9090/plugins/restapi/userservice?type=grouplist&secret=bigsecret -Which replies an XML group list formatted like this: -```xml - - group1 - group2 - -``` - -The following example gets all groups for a specific user - -http://example.com:9090/plugins/restapi/userservice?type=usergrouplist&secret=bigsecret&username=kafka -Which replies an XML group list formatted like this: -```xml - - usergroup1 - usergroup2 - -``` - -When sending double characters (Chinese/Japanese/Korean etc.) you should URLEncode the string as utf8. -In Java this is done like this - -> URLEncoder.encode(username, "UTF-8")); - -If the strings are encoded incorrectly, double byte characters will look garbeled in the Admin Console. - -## Server Reply -The server will reply to all User Service requests with an XML result page. If the request was processed successfully the return will be a "result" element with a text body of "OK", or an XML grouplist formatted like in the example for "grouplist" and "usergrouplist" above. If the request was unsuccessful, the return will be an "error" element with a text body of one of the following error strings. - -| Error String | Description | -|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| IllegalArgumentException | One of the parameters passed in to the User Service was bad. | -| UserNotFoundException | No user of the name specified, for a delete or update operation, exists on this server. For 'update_roster' operation, roster item to be updated was not found. | -| UserAlreadyExistsException | A user with the same name as the user about to be added, already exists. For 'add_roster' operation, roster item with the same JID already exists. | -| RequestNotAuthorised | The supplied secret does not match the secret specified in the Admin Console or the requester is not a valid IP address. | -| UserServiceDisabled | The User Service is currently set to disabled in the Admin Console. | -| SharedGroupException | Roster item can not be added/deleted to/from a shared group for operations with roster. | - diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/AuthFilter.java b/src/java/org/jivesoftware/openfire/plugin/rest/AuthFilter.java index 7a5b1ef80..420b7fffa 100644 --- a/src/java/org/jivesoftware/openfire/plugin/rest/AuthFilter.java +++ b/src/java/org/jivesoftware/openfire/plugin/rest/AuthFilter.java @@ -76,12 +76,6 @@ public void filter(ContainerRequestContext containerRequest) throws IOException LOG.debug("Authentication was bypassed because of OPTIONS request"); return; } - - // To be backwards compatible to userservice 1.* - if (containerRequest.getUriInfo().getRequestUri().getPath().contains("restapi/v1/userservice")) { - LOG.info("Deprecated 'userservice' endpoint was used. Please switch to the new endpoints"); - return; - } if (!RESTServicePlugin.ALLOWED_IPS.getValue().isEmpty()) { // Get client's IP address. Do not inspect headers like 'X-Forwarded-For' here: these can be spoofed by the client. diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceLegacyController.java b/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceLegacyController.java deleted file mode 100644 index ef4db1272..000000000 --- a/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceLegacyController.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2005-2008 Jive Software. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jivesoftware.openfire.plugin.rest.controller; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.StringTokenizer; - -import org.jivesoftware.openfire.SharedGroupException; -import org.jivesoftware.openfire.XMPPServer; -import org.jivesoftware.openfire.group.Group; -import org.jivesoftware.openfire.group.GroupAlreadyExistsException; -import org.jivesoftware.openfire.group.GroupManager; -import org.jivesoftware.openfire.group.GroupNameInvalidException; -import org.jivesoftware.openfire.group.GroupNotFoundException; -import org.jivesoftware.openfire.lockout.LockOutManager; -import org.jivesoftware.openfire.roster.Roster; -import org.jivesoftware.openfire.roster.RosterItem; -import org.jivesoftware.openfire.roster.RosterManager; -import org.jivesoftware.openfire.user.User; -import org.jivesoftware.openfire.user.UserAlreadyExistsException; -import org.jivesoftware.openfire.user.UserManager; -import org.jivesoftware.openfire.user.UserNotFoundException; -import org.xmpp.packet.JID; - -/** - * Plugin that allows the administration of users via HTTP requests. - * - * @author Justin Hunt - */ -public class UserServiceLegacyController { - - /** The Constant INSTANCE. */ - public static final UserServiceLegacyController INSTANCE = new UserServiceLegacyController(); - - /** The user manager. */ - private UserManager userManager; - - /** The roster manager. */ - private RosterManager rosterManager; - - /** The server. */ - private XMPPServer server; - - /** - * Gets the single instance of UserServiceLegacyController. - * - * @return single instance of UserServiceLegacyController - */ - public static UserServiceLegacyController getInstance() { - return INSTANCE; - } - - /** - * Instantiates a new user service legacy controller. - */ - private UserServiceLegacyController() { - server = XMPPServer.getInstance(); - userManager = server.getUserManager(); - rosterManager = server.getRosterManager(); - } - - /** - * Creates the user. - * - * @param username the username - * @param password the password - * @param name the name - * @param email the email - * @param groupNames the group names - * @throws UserAlreadyExistsException the user already exists exception - * @throws GroupAlreadyExistsException the group already exists exception - * @throws UserNotFoundException the user not found exception - * @throws GroupNotFoundException the group not found exception - */ - public void createUser(String username, String password, String name, String email, String groupNames) - throws UserAlreadyExistsException, GroupAlreadyExistsException, UserNotFoundException, - GroupNotFoundException, GroupNameInvalidException - { - userManager.createUser(username, password, name, email); - userManager.getUser(username); - - if (groupNames != null) { - Collection groups = new ArrayList(); - StringTokenizer tkn = new StringTokenizer(groupNames, ","); - - while (tkn.hasMoreTokens()) { - String groupName = tkn.nextToken(); - Group group = null; - - try { - group = GroupManager.getInstance().getGroup(groupName); - } catch (GroupNotFoundException e) { - // Create this group ; - group = GroupManager.getInstance().createGroup(groupName); - group.getProperties().put("sharedRoster.showInRoster", "nobody"); - group.getProperties().put("sharedRoster.displayName", groupName); - group.getProperties().put("sharedRoster.groupList", ""); - } - groups.add(group); - } - for (Group group : groups) { - group.getMembers().add(server.createJID(username, null)); - } - } - } - - /** - * Delete user. - * - * @param username the username - * @throws UserNotFoundException the user not found exception - * @throws SharedGroupException the shared group exception - */ - public void deleteUser(String username) throws UserNotFoundException, SharedGroupException { - User user = getUser(username); - userManager.deleteUser(user); - - rosterManager.deleteRoster(server.createJID(username, null)); - } - - /** - * Lock Out on a given username. - * - * @param username the username of the local user to disable. - * @throws UserNotFoundException if the requested user does not exist in the local server. - */ - public void disableUser(String username) throws UserNotFoundException { - getUser(username); - LockOutManager.getInstance().disableAccount(username, null, null); - } - - /** - * Remove the lockout on a given username. - * - * @param username the username of the local user to enable. - * @throws UserNotFoundException if the requested user does not exist in the local server. - */ - public void enableUser(String username) throws UserNotFoundException { - getUser(username); - LockOutManager.getInstance().enableAccount(username); - } - - /** - * Update user. - * - * @param username the username - * @param password the password - * @param name the name - * @param email the email - * @param groupNames the group names - * @throws UserNotFoundException the user not found exception - * @throws GroupAlreadyExistsException the group already exists exception - */ - public void updateUser(String username, String password, String name, String email, String groupNames) - throws UserNotFoundException, GroupAlreadyExistsException, GroupNameInvalidException - { - User user = getUser(username); - if (password != null) - user.setPassword(password); - if (name != null) - user.setName(name); - if (email != null) - user.setEmail(email); - - if (groupNames != null) { - Collection newGroups = new ArrayList(); - StringTokenizer tkn = new StringTokenizer(groupNames, ","); - - while (tkn.hasMoreTokens()) { - String groupName = tkn.nextToken(); - Group group = null; - - try { - group = GroupManager.getInstance().getGroup(groupName); - } catch (GroupNotFoundException e) { - // Create this group ; - group = GroupManager.getInstance().createGroup(groupName); - group.getProperties().put("sharedRoster.showInRoster", "nobody"); - group.getProperties().put("sharedRoster.displayName", groupName); - group.getProperties().put("sharedRoster.groupList", ""); - } - - newGroups.add(group); - } - - Collection existingGroups = GroupManager.getInstance().getGroups(user); - // Get the list of groups to add to the user - Collection groupsToAdd = new ArrayList(newGroups); - groupsToAdd.removeAll(existingGroups); - // Get the list of groups to remove from the user - Collection groupsToDelete = new ArrayList(existingGroups); - groupsToDelete.removeAll(newGroups); - - // Add the user to the new groups - for (Group group : groupsToAdd) { - group.getMembers().add(server.createJID(username, null)); - } - // Remove the user from the old groups - for (Group group : groupsToDelete) { - group.getMembers().remove(server.createJID(username, null)); - } - } - } - - /** - * Add new roster item for specified user. - * - * @param username the username of the local user to add roster item to. - * @param itemJID the JID of the roster item to be added. - * @param itemName the nickname of the roster item. - * @param subscription the type of subscription of the roster item. Possible values - * are: -1(remove), 0(none), 1(to), 2(from), 3(both). - * @param groupNames the name of a group to place contact into. - * @throws UserNotFoundException if the user does not exist in the local server. - * @throws UserAlreadyExistsException if roster item with the same JID already exists. - * @throws SharedGroupException if roster item cannot be added to a shared group. - */ - public void addRosterItem(String username, String itemJID, String itemName, String subscription, String groupNames) - throws UserNotFoundException, UserAlreadyExistsException, SharedGroupException { - getUser(username); - Roster r = rosterManager.getRoster(username); - JID j = new JID(itemJID); - - try { - r.getRosterItem(j); - throw new UserAlreadyExistsException(j.toBareJID()); - } catch (UserNotFoundException e) { - // Roster item does not exist. Try to add it. - } - - if (r != null) { - List groups = new ArrayList(); - if (groupNames != null) { - StringTokenizer tkn = new StringTokenizer(groupNames, ","); - while (tkn.hasMoreTokens()) { - groups.add(tkn.nextToken()); - } - } - RosterItem ri = r.createRosterItem(j, itemName, groups, false, true); - if (subscription == null) { - subscription = "0"; - } - ri.setSubStatus(RosterItem.SubType.getTypeFromInt(Integer.parseInt(subscription))); - r.updateRosterItem(ri); - } - } - - /** - * Update roster item for specified user. - * - * @param username the username of the local user to update roster item for. - * @param itemJID the JID of the roster item to be updated. - * @param itemName the nickname of the roster item. - * @param subscription the type of subscription of the roster item. Possible values - * are: -1(remove), 0(none), 1(to), 2(from), 3(both). - * @param groupNames the name of a group. - * @throws UserNotFoundException if the user does not exist in the local server or roster item - * does not exist. - * @throws SharedGroupException if roster item cannot be added to a shared group. - */ - public void updateRosterItem(String username, String itemJID, String itemName, String subscription, - String groupNames) throws UserNotFoundException, SharedGroupException { - getUser(username); - Roster r = rosterManager.getRoster(username); - JID j = new JID(itemJID); - - RosterItem ri = r.getRosterItem(j); - - List groups = new ArrayList(); - if (groupNames != null) { - StringTokenizer tkn = new StringTokenizer(groupNames, ","); - while (tkn.hasMoreTokens()) { - groups.add(tkn.nextToken()); - } - } - - ri.setGroups(groups); - ri.setNickname(itemName); - - if (subscription == null) { - subscription = "0"; - } - ri.setSubStatus(RosterItem.SubType.getTypeFromInt(Integer.parseInt(subscription))); - r.updateRosterItem(ri); - } - - /** - * Delete roster item for specified user. No error returns if nothing to - * delete. - * - * @param username - * the username of the local user to add roster item to. - * @param itemJID - * the JID of the roster item to be deleted. - * @throws UserNotFoundException - * if the user does not exist in the local server. - * @throws SharedGroupException - * if roster item cannot be deleted from a shared group. - */ - public void deleteRosterItem(String username, String itemJID) throws UserNotFoundException, SharedGroupException { - getUser(username); - Roster r = rosterManager.getRoster(username); - JID j = new JID(itemJID); - - // No roster item is found. Uncomment the following line to throw - // UserNotFoundException. - // r.getRosterItem(j); - - r.deleteRosterItem(j, true); - } - - /** - * Returns the the requested user or null if there are any problems - * that don't throw an error. - * - * @param username - * the username of the local user to retrieve. - * @return the requested user. - * @throws UserNotFoundException - * if the requested user does not exist in the local server. - */ - private User getUser(String username) throws UserNotFoundException { - JID targetJID = server.createJID(username, null); - // Check that the sender is not requesting information of a remote - // server entity - if (targetJID.getNode() == null) { - // Sender is requesting presence information of an anonymous user - throw new UserNotFoundException("Username is null"); - } - return userManager.getUser(targetJID.getNode()); - } - - /** - * Returns all group names or an empty collection. - * - * @return the all groups - */ - public Collection getAllGroups() { - Collection groups = GroupManager.getInstance().getGroups(); - Collection groupNames = new ArrayList(); - for (Group group : groups) { - groupNames.add(group.getName()); - } - return groupNames; - } - - /** - * Returns all group names or an empty collection for specific user. - * - * @param username the username - * @return the user groups - * @throws UserNotFoundException the user not found exception - */ - public Collection getUserGroups(String username) throws UserNotFoundException { - User user = getUser(username); - Collection groups = GroupManager.getInstance().getGroups(user); - Collection groupNames = new ArrayList(); - for (Group group : groups) { - groupNames.add(group.getName()); - } - return groupNames; - } -} diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java b/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java index 3d9b8b6cd..42eb84b11 100644 --- a/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java +++ b/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java @@ -172,7 +172,6 @@ public JerseyWrapper(@Context ServletConfig servletConfig) { UserLockoutService.class, UserRosterService.class, UserService.class, - UserServiceLegacy.class, UserVCardService.class ); diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/service/UserServiceLegacy.java b/src/java/org/jivesoftware/openfire/plugin/rest/service/UserServiceLegacy.java deleted file mode 100644 index 157c78a99..000000000 --- a/src/java/org/jivesoftware/openfire/plugin/rest/service/UserServiceLegacy.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2022-2026 Ignite Realtime Foundation. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jivesoftware.openfire.plugin.rest.service; - -import gnu.inet.encoding.Stringprep; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.jivesoftware.openfire.SharedGroupException; -import org.jivesoftware.openfire.XMPPServer; -import org.jivesoftware.openfire.plugin.rest.RESTServicePlugin; -import org.jivesoftware.openfire.plugin.rest.controller.UserServiceLegacyController; -import org.jivesoftware.openfire.user.UserAlreadyExistsException; -import org.jivesoftware.openfire.user.UserNotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xmpp.packet.JID; - -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.io.PrintWriter; - -@Path("restapi/v1") -@Tag(name = "UserService (deprecated)", description = "Undocumented UserService endpoint, retained for backwards compatibility.") -public class UserServiceLegacy { - private static Logger LOG = LoggerFactory.getLogger(UserServiceLegacy.class); - - @Context - private HttpServletRequest request; - - @Context - private HttpServletResponse response; - - private RESTServicePlugin plugin; - - private UserServiceLegacyController userServiceController; - - @PostConstruct - public void init() { - plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager() - .getPluginByName("REST API").orElse(null); - userServiceController = UserServiceLegacyController.getInstance(); - } - - @POST - @Path("/userservice") - public void userSerivcePostRequest() throws IOException { - userSerivceRequest(); - } - - @GET - @Path("/userservice") - public Response userSerivceRequest() throws IOException { - // Printwriter for writing out responses to browser - PrintWriter out = response.getWriter(); - - if (!RESTServicePlugin.ALLOWED_IPS.getValue().isEmpty()) { - // Get client's IP address. Do not inspect headers like 'X-Forwarded-For' here: these can be spoofed by the client. - // When Openfire is configured to be accessed through a reverse proxy, its web server already replaces the remote - // address with the value from such headers, but only for requests from proxies that are configured to be trusted. - final String ipAddress = request.getRemoteAddr(); - if (!RESTServicePlugin.ALLOWED_IPS.getValue().contains(ipAddress)) { - LOG.warn("User service rejected service to IP address: " + ipAddress); - replyError("RequestNotAuthorised", response, out); - return Response.status(200).build(); - } - } - - String username = request.getParameter("username"); - String password = request.getParameter("password"); - String name = request.getParameter("name"); - String email = request.getParameter("email"); - String type = request.getParameter("type"); - String secret = request.getParameter("secret"); - String groupNames = request.getParameter("groups"); - String item_jid = request.getParameter("item_jid"); - String sub = request.getParameter("subscription"); - // No defaults, add, delete, update only - // type = type == null ? "image" : type; - - // Check that our plugin is enabled. - if (!RESTServicePlugin.ENABLED.getValue()) { - LOG.warn("User service plugin is disabled: " + request.getQueryString()); - replyError("UserServiceDisabled", response, out); - return Response.status(200).build(); - } - - // Check this request is authorised - if (secret == null || secret.isEmpty() || !secret.equals(RESTServicePlugin.SECRET.getValue())) { - LOG.warn("An unauthorised user service request was received: " + request.getQueryString()); - replyError("RequestNotAuthorised", response, out); - return Response.status(200).build(); - } - - // Some checking is required on the username - if (username == null && !"grouplist".equals(type)) { - replyError("IllegalArgumentException", response, out); - return Response.status(200).build(); - } - - if ((type.equals("add_roster") || type.equals("update_roster") || type.equals("delete_roster")) - && (item_jid == null || !(sub == null || sub.equals("-1") || sub.equals("0") || sub.equals("1") - || sub.equals("2") || sub.equals("3")))) { - replyError("IllegalArgumentException", response, out); - return Response.status(200).build(); - } - - // Check the request type and process accordingly - try { - if ("grouplist".equals(type)) { - String message = ""; - for (String groupname : userServiceController.getAllGroups()) { - message += "" + groupname + ""; - } - replyMessage(message, response, out); - } else { - username = username.trim().toLowerCase(); - username = JID.escapeNode(username); - username = Stringprep.nodeprep(username); - if ("add".equals(type)) { - userServiceController.createUser(username, password, name, email, groupNames); - replyMessage("ok", response, out); - } else if ("delete".equals(type)) { - userServiceController.deleteUser(username); - replyMessage("ok", response, out); - } else if ("enable".equals(type)) { - userServiceController.enableUser(username); - replyMessage("ok", response, out); - } else if ("disable".equals(type)) { - userServiceController.disableUser(username); - replyMessage("ok", response, out); - } else if ("update".equals(type)) { - userServiceController.updateUser(username, password, name, email, groupNames); - replyMessage("ok", response, out); - } else if ("add_roster".equals(type)) { - userServiceController.addRosterItem(username, item_jid, name, sub, groupNames); - replyMessage("ok", response, out); - } else if ("update_roster".equals(type)) { - userServiceController.updateRosterItem(username, item_jid, name, sub, groupNames); - replyMessage("ok", response, out); - } else if ("delete_roster".equals(type)) { - userServiceController.deleteRosterItem(username, item_jid); - replyMessage("ok", response, out); - } else if ("usergrouplist".equals(type)) { - String message = ""; - for (String groupname : userServiceController.getUserGroups(username)) { - message += "" + groupname + ""; - } - replyMessage(message, response, out); - } else { - LOG.warn("The userService servlet received an invalid request of type: " + type); - // TODO Do something - } - } - } catch (UserAlreadyExistsException e) { - replyError("UserAlreadyExistsException", response, out); - } catch (UserNotFoundException e) { - replyError("UserNotFoundException", response, out); - } catch (IllegalArgumentException e) { - replyError("IllegalArgumentException", response, out); - } catch (SharedGroupException e) { - replyError("SharedGroupException", response, out); - } catch (Exception e) { - LOG.error("Unexpected error while processing 'userservice' request of type '{}' for username '{}'", type, username, e); - replyError(e.toString(), response, out); - } - return Response.status(200).build(); - } - - private void replyMessage(String message, HttpServletResponse response, PrintWriter out) { - response.setContentType("text/xml"); - out.println("" + message + ""); - out.flush(); - } - - private void replyError(String error, HttpServletResponse response, PrintWriter out) { - response.setContentType("text/xml"); - out.println("" + error + ""); - out.flush(); - } -}