Skip to content
6 changes: 6 additions & 0 deletions i18n/src/main/resources/openfire_i18n.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2905,6 +2905,7 @@ pubsub.node.affiliates.delete.title=Delete Affiliate
pubsub.node.affiliates.delete.info=Affiliation details:
pubsub.node.affiliates.delete.info2=Current subscriptions for this affiliation (These will also be deleted):
pubsub.node.affiliates.delete.info3=Are you sure you want to delete the affiliation?
pubsub.node.affiliates.delete.confirm=Are you sure you want to delete the affiliation of {0} from node {1}?
pubsub.node.affiliates.delete.table.no_subscriptions=This Affiliate has no subscriptions to the Node.
pubsub.node.affiliates.delete.delete_affiliate=Delete Affiliate

Expand All @@ -2925,6 +2926,11 @@ pubsub.node.subscribers.expires=Expires
pubsub.node.subscribers.table.info=Current node subscribers are listed in the following table:
pubsub.node.subscribers.table.no_subscribers=The Node has no subscribers.
pubsub.node.subscribers.deleted=Deleted subscription owned by {0} from the node.
# pubsub.node.subscribers.confirm_delete=Are you sure you want to delete this subscriber?
pubsub.node.subscribers.delete.title=Delete Subscriber
pubsub.node.subscribers.delete.info=Subscriber details:
pubsub.node.subscribers.delete.info3=Are you sure you want to delete the subscriber?
pubsub.node.subscribers.delete.delete_subscriber=Delete Subscriber

# PubSub service tab

Expand Down
82 changes: 13 additions & 69 deletions xmppserver/src/main/webapp/pubsub-node-affiliates-delete.jsp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%--
-
- Copyright (C) 2017-2025 Ignite Realtime Foundation. All rights reserved.
- Copyright (C) 2017-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.
Expand Down Expand Up @@ -47,6 +47,7 @@
String csrfParam = ParamUtils.getParameter(request, "csrf");
String nodeID = ParamUtils.getParameter(request,"nodeID");
String affiliateJID = ParamUtils.getParameter(request,"affiliateJID");
String affiliationParam = ParamUtils.getParameter(request,"affiliation");

final Map<String, String> errors = new HashMap<>();

Expand Down Expand Up @@ -134,8 +135,14 @@
CookieUtils.setCookie(request, response, "csrf", csrfParam, -1);
pageContext.setAttribute("csrf", csrfParam);

String affiliation = affiliationParam;
if (affiliation == null && affiliate != null) {
affiliation = affiliate.getAffiliation().name();
}

pageContext.setAttribute("node", node);
pageContext.setAttribute("affiliate", affiliate);
pageContext.setAttribute("affiliation", affiliation);
pageContext.setAttribute("owner", owner);
pageContext.setAttribute("errors", errors);
%>
Expand Down Expand Up @@ -171,81 +178,18 @@
</c:forEach>

<p>
<fmt:message key="pubsub.node.affiliates.delete.info" />
</p>

<div class="jive-table">
<table style="width: 100%">
<thead>
<tr>
<th scope="col"><fmt:message key="pubsub.node.summary.id" /></th>
<th scope="col"><fmt:message key="pubsub.node.affiliates.jid" /></th>
<th scope="col"><fmt:message key="pubsub.node.affiliates.affiliation" /></th>
</tr>
</thead>
<tbody>
<tr>
<td><c:out value="${node.nodeID}"/></td>
<td><c:out value="${affiliate.JID.toBareJID()}"/></td>
<td><c:out value="${affiliate.affiliation.name()}"/></td>
</tr>
</tbody>
</table>
</div>
<br>
<br>
<p>
<fmt:message key="pubsub.node.affiliates.delete.info2" />
</p>

<div class="jive-table">
<table style="width: 100%">
<thead>
<tr>
<th scope="col"><fmt:message key="pubsub.node.subscribers.owner" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.resource" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.status" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.expires" /></th>
</tr>
</thead>
<tbody>
<c:if test="${empty affiliate.subscriptions}">
<tr>
<td style="text-align: center" colspan="4">
<fmt:message key="pubsub.node.affiliates.delete.table.no_subscriptions" />
</td>
</tr>
</c:if>
<c:forEach var="subscription" items="${affiliate.subscriptions}">
<tr>
<td>
<c:out value="${subscription.owner.toBareJID()}"/>
</td>
<td>
<c:out value="${subscription.JID.resource}"/>
</td>
<td>
<c:out value="${subscription.state.name()}"/>
</td>
<td>
<fmt:formatDate type="both" dateStyle="medium" timeStyle="short" value="${subscription.expire}" />
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<br>
<br>
<p>
<fmt:message key="pubsub.node.affiliates.delete.info3" />
<fmt:message key="pubsub.node.affiliates.delete.confirm">
<fmt:param value="<b>${fn:escapeXml(affiliateJID)}</b>" />
<fmt:param value="<b>${fn:escapeXml(nodeID)}</b>" />
</fmt:message>
</p>

<form action="pubsub-node-affiliates-delete.jsp">
<input type="hidden" name="csrf" value="${csrf}">
<input type="hidden" name="nodeID" value="${fn:escapeXml(node.nodeID)}">
<input type="hidden" name="owner" value="${fn:escapeXml(owner)}">
<input type="hidden" name="affiliateJID" value="${fn:escapeXml(affiliate.JID.toBareJID())}">
<input type="hidden" name="affiliation" value="${fn:escapeXml(affiliation)}">

<input type="submit" name="delete" value="<fmt:message key="pubsub.node.affiliates.delete.delete_affiliate" />">
<input type="submit" name="cancel" value="<fmt:message key="global.cancel" />">
Expand Down
5 changes: 3 additions & 2 deletions xmppserver/src/main/webapp/pubsub-node-affiliates.jsp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%--
-
- Copyright (C) 2017-2025 Ignite Realtime Foundation. All rights reserved.
- Copyright (C) 2017-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.
Expand Down Expand Up @@ -183,7 +183,7 @@
<tbody>
<c:if test="${empty affiliates}">
<tr>
<td style="text-align: center" colspan="4">
<td style="text-align: center" colspan="5">
<fmt:message key="pubsub.node.affiliates.table.no_affiliates" />
</td>
</tr>
Expand Down Expand Up @@ -220,6 +220,7 @@
<c:param name="nodeID" value="${node.nodeID}" />
<c:param name="owner" value="${owner}" />
<c:param name="affiliateJID" value="${affiliate.JID.toBareJID()}" />
<c:param name="affiliation" value="${affiliate.affiliation.name()}" />
</c:url>
<a href="${url}" title="<fmt:message key="global.click_delete" />">
<img src="images/delete-16x16.gif" alt="">
Expand Down
202 changes: 202 additions & 0 deletions xmppserver/src/main/webapp/pubsub-node-subscriber-delete.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<%--
-
- Copyright (C) 2017-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.
--%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="org.jivesoftware.openfire.pep.PEPServiceInfo,
org.jivesoftware.openfire.pubsub.NodeSubscription,
org.jivesoftware.openfire.pubsub.PubSubServiceInfo,
org.jivesoftware.util.*,
org.jivesoftware.openfire.pubsub.Node,
org.jivesoftware.openfire.XMPPServer,
org.xmpp.packet.JID,
java.net.URLEncoder,
java.util.HashMap,
java.util.Map"
errorPage="error.jsp"
%>
<%@ page import="java.nio.charset.StandardCharsets" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="admin" prefix="admin" %>

<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
<% webManager.init(request, response, session, application, out ); %>

<% // Get parameters //
boolean cancel = ParamUtils.getParameter(request,"cancel") != null;
boolean delete = ParamUtils.getParameter(request,"delete") != null;
Cookie csrfCookie = CookieUtils.getCookie(request, "csrf");
String csrfParam = ParamUtils.getParameter(request, "csrf");
String nodeID = ParamUtils.getParameter(request,"nodeID");
String deleteID = ParamUtils.getParameter(request,"deleteID");

final Map<String, String> errors = new HashMap<>();

String ownerString = ParamUtils.getParameter( request, "owner" );
if ( ownerString == null )
{
ownerString = ParamUtils.getParameter( request, "username" );
}

JID owner = null;
if (ownerString != null)
{
if ( ownerString.contains( "@" ) )
{
owner = new JID( ownerString ).asBareJID();
}
else
{
owner = XMPPServer.getInstance().createJID( ownerString, null );
}
}

if (delete) {
if (csrfCookie == null || csrfParam == null || !csrfCookie.getValue().equals(csrfParam)) {
delete = false;
errors.put("csrf", "CSRF Failure!");
}
}

// Handle a cancel
if (cancel) {
response.sendRedirect("pubsub-node-subscribers.jsp?nodeID="+URLEncoder.encode(nodeID, StandardCharsets.UTF_8) + (owner != null ? "&owner=" + URLEncoder.encode(owner.toBareJID(), StandardCharsets.UTF_8) : ""));
return;
}

PubSubServiceInfo pubSubServiceInfo;
if ( owner == null )
{
pubSubServiceInfo = webManager.getPubSubInfo();
}
else
{
pubSubServiceInfo = new PEPServiceInfo( owner );
}

// Load the node object
Node node = pubSubServiceInfo.getNode(nodeID);
if (node == null) {
// The requested node does not exist so return to the list of the existing node
response.sendRedirect("pubsub-node-summary.jsp" + (owner != null ? "?owner=" + URLEncoder.encode(owner.toBareJID(), StandardCharsets.UTF_8) : ""));
return;
}

NodeSubscription subscription = node.getSubscription(deleteID);

// Handle a subscriber delete:
if (errors.isEmpty() && delete) {
if (subscription != null) {
node.cancelSubscription(subscription);

// Log the event
webManager.logEvent("Cancelled subscription ID: " + deleteID + ", from node ID: " + nodeID, "Owner: " + subscription.getOwner().toBareJID());
}
// Done, so redirect
response.sendRedirect("pubsub-node-subscribers.jsp?nodeID=" + URLEncoder.encode(nodeID, StandardCharsets.UTF_8)
+ "&deleteSuccess=true"
+ (owner != null ? "&owner=" + URLEncoder.encode(owner.toBareJID(), StandardCharsets.UTF_8) : "")
+ (subscription != null ? "&ownerOfDeleted=" + URLEncoder.encode(subscription.getOwner().toBareJID(), StandardCharsets.UTF_8) : ""));
return;
}

csrfParam = StringUtils.randomString(15);
CookieUtils.setCookie(request, response, "csrf", csrfParam, -1);
pageContext.setAttribute("csrf", csrfParam);

pageContext.setAttribute("node", node);
pageContext.setAttribute("subscription", subscription);
pageContext.setAttribute("owner", owner);
pageContext.setAttribute("errors", errors);
%>

<html>
<head>
<title><fmt:message key="pubsub.node.subscribers.delete.title"/></title>
<c:choose>
<c:when test="${not empty owner and owner.domain eq webManager.serverInfo.XMPPDomain}">
<meta name="subPageID" content="user-pep-node-summary"/>
<meta name="extraParams" content="username=${admin:urlEncode(owner.node)}&nodeID=${admin:urlEncode(node.nodeID)}" />
</c:when>
<c:otherwise>
<meta name="subPageID" content="pubsub-node-subscribers"/>
<meta name="extraParams" content="nodeID=${admin:urlEncode(node.nodeID)}"/>
</c:otherwise>
</c:choose>
</head>
<body>

<c:forEach var="err" items="${errors}">
<admin:infobox type="error">
<c:choose>
<c:when test="${err.key eq 'csrf'}"><fmt:message key="global.csrf.failed" /></c:when>
<c:otherwise>
<c:if test="${not empty err.value}">
<fmt:message key="admin.error"/>: <c:out value="${err.value}"/>
</c:if>
(<c:out value="${err.key}"/>)
</c:otherwise>
</c:choose>
</admin:infobox>
</c:forEach>

<p>
<fmt:message key="pubsub.node.subscribers.delete.info" />
</p>

<div class="jive-table">
<table style="width: 100%">
<thead>
<tr>
<th scope="col"><fmt:message key="pubsub.node.subscribers.owner" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.resource" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.affiliation" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.status" /></th>
<th scope="col"><fmt:message key="pubsub.node.subscribers.expires" /></th>
</tr>
</thead>
<tbody>
<tr>
<td><c:out value="${subscription.owner.toBareJID()}"/></td>
<td><c:out value="${subscription.JID.resource}"/></td>
<td><c:out value="${subscription.affiliate.affiliation.name()}"/></td>
<td><c:out value="${subscription.state.name()}"/></td>
<td><fmt:formatDate type="both" dateStyle="medium" timeStyle="short" value="${subscription.expire}" /></td>
</tr>
</tbody>
</table>
</div>

<br>
<br>
<p>
<fmt:message key="pubsub.node.subscribers.delete.info3" />
</p>

<form action="pubsub-node-subscriber-delete.jsp">
<input type="hidden" name="csrf" value="${csrf}">
<input type="hidden" name="nodeID" value="${fn:escapeXml(node.nodeID)}">
<input type="hidden" name="owner" value="${fn:escapeXml(owner)}">
<input type="hidden" name="deleteID" value="${fn:escapeXml(subscription.ID)}">

<input type="submit" name="delete" value="<fmt:message key="pubsub.node.subscribers.delete.delete_subscriber" />">
<input type="submit" name="cancel" value="<fmt:message key="global.cancel" />">
</form>

</body>
</html>
Loading
Loading