001/**
002 *
003 * Copyright 2016-2021 Florian Schmaus
004 *
005 * This file is part of smack-examples.
006 *
007 * smack-examples is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 3 of the License, or
010 * (at your option) any later version.
011 *
012 * This program is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with this program; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
020 */
021package org.igniterealtime.smack.examples;
022
023import java.io.IOException;
024import java.security.KeyManagementException;
025import java.security.NoSuchAlgorithmException;
026import java.util.Date;
027import java.util.logging.Logger;
028
029import org.jivesoftware.smack.SmackException;
030import org.jivesoftware.smack.SmackException.NoResponseException;
031import org.jivesoftware.smack.SmackException.NotConnectedException;
032import org.jivesoftware.smack.XMPPConnection;
033import org.jivesoftware.smack.XMPPException;
034import org.jivesoftware.smack.XMPPException.XMPPErrorException;
035import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection;
036import org.jivesoftware.smack.packet.Message;
037import org.jivesoftware.smack.tcp.XMPPTCPConnection;
038import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
039import org.jivesoftware.smack.util.TLSUtils;
040import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
041import org.jivesoftware.smackx.iqregister.AccountManager;
042
043import org.jxmpp.jid.DomainBareJid;
044import org.jxmpp.jid.impl.JidCreate;
045import org.jxmpp.jid.parts.Localpart;
046import org.jxmpp.stringprep.XmppStringprepException;
047import org.jxmpp.util.XmppDateTime;
048
049public class XmppTools {
050
051    public static void main(String[] args) throws SmackException, IOException, XMPPException, InterruptedException,
052            KeyManagementException, NoSuchAlgorithmException {
053        boolean one = createAccount("xmpp.foobar.io", "smack1", "smack1");
054        boolean two = createAccount("xmpp.foobar.io", "smack2", "smack2");
055        // CHECKSTYLE:OFF
056        System.out.println("Account created: " + one + ' ' + two);
057        // CHECKSTYLE:ON
058    }
059
060    public static boolean supportsIbr(String xmppDomain) throws SmackException, IOException, XMPPException,
061            InterruptedException, KeyManagementException, NoSuchAlgorithmException {
062        DomainBareJid xmppDomainJid = JidCreate.domainBareFrom(xmppDomain);
063        return supportsIbr(xmppDomainJid);
064    }
065
066    public static boolean supportsIbr(DomainBareJid xmppDomain) throws SmackException, IOException, XMPPException,
067            InterruptedException, KeyManagementException, NoSuchAlgorithmException {
068        XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder()
069                .setXmppDomain(xmppDomain);
070        TLSUtils.acceptAllCertificates(configBuilder);
071        XMPPTCPConnectionConfiguration config = configBuilder.build();
072        XMPPTCPConnection connection = new XMPPTCPConnection(config);
073        connection.connect();
074        try {
075            return supportsIbr(connection);
076        } finally {
077            connection.disconnect();
078        }
079    }
080
081    public static boolean supportsIbr(XMPPConnection connection)
082            throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
083        AccountManager accountManager = AccountManager.getInstance(connection);
084        return accountManager.supportsAccountCreation();
085    }
086
087    public static boolean createAccount(String xmppDomain, String username, String password)
088            throws KeyManagementException, NoSuchAlgorithmException, SmackException, IOException, XMPPException,
089            InterruptedException {
090        DomainBareJid xmppDomainJid = JidCreate.domainBareFrom(xmppDomain);
091        Localpart localpart = Localpart.from(username);
092        return createAccount(xmppDomainJid, localpart, password);
093    }
094
095    public static boolean createAccount(DomainBareJid xmppDomain, Localpart username, String password)
096            throws KeyManagementException, NoSuchAlgorithmException, SmackException, IOException, XMPPException,
097            InterruptedException {
098        XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder()
099                .setXmppDomain(xmppDomain);
100        TLSUtils.acceptAllCertificates(configBuilder);
101        XMPPTCPConnectionConfiguration config = configBuilder.build();
102        XMPPTCPConnection connection = new XMPPTCPConnection(config);
103        connection.connect();
104        try {
105            if (!supportsIbr(connection))
106                return false;
107
108            AccountManager accountManager = AccountManager.getInstance(connection);
109            accountManager.createAccount(username, password);
110            return true;
111        } finally {
112            connection.disconnect();
113        }
114    }
115
116    public static void modularConnectionTest(ModularXmppClientToServerConnection connection, String messageTo) throws XMPPException, SmackException, IOException, InterruptedException {
117        connection.addConnectionStateMachineListener((event, c) -> {
118            Logger.getAnonymousLogger().info("Connection event: " + event);
119        });
120
121        connection.connect();
122
123        connection.login();
124
125        XmppTools.sendItsAlive(messageTo, connection);
126
127        Thread.sleep(1000);
128
129        connection.disconnect();
130
131        ModularXmppClientToServerConnection.Stats connectionStats = connection.getStats();
132        ServiceDiscoveryManager.Stats serviceDiscoveryManagerStats = ServiceDiscoveryManager.getInstanceFor(connection).getStats();
133
134        // CHECKSTYLE:OFF
135        System.out.println("NIO successfully finished, yeah!\n" + connectionStats + '\n' + serviceDiscoveryManagerStats);
136        // CHECKSTYLE:ON
137    }
138
139    public static void sendItsAlive(String to, XMPPConnection connection)
140                    throws XmppStringprepException, NotConnectedException, InterruptedException {
141        if (to == null) {
142            return;
143        }
144
145        Message message = connection.getStanzaFactory().buildMessageStanza()
146                        .to(to)
147                        .setBody("It is alive! " + XmppDateTime.formatXEP0082Date(new Date()))
148                        .build();
149        connection.sendStanza(message);
150    }
151}