/*
* Copyright 2016 Sam Sun <me@samczsun.com>
*
* 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 com.samczsun.skype4j.internal.client;
import com.eclipsesource.json.JsonObject;
import com.samczsun.skype4j.chat.GroupChat;
import com.samczsun.skype4j.exceptions.ConnectionException;
import com.samczsun.skype4j.exceptions.InvalidCredentialsException;
import com.samczsun.skype4j.exceptions.NotParticipatingException;
import com.samczsun.skype4j.exceptions.handler.ErrorHandler;
import com.samczsun.skype4j.internal.Endpoints;
import com.samczsun.skype4j.internal.SkypeImpl;
import com.samczsun.skype4j.internal.Utils;
import com.samczsun.skype4j.internal.utils.UncheckedRunnable;
import com.samczsun.skype4j.participants.info.Contact;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
public class GuestClient extends SkypeImpl {
private final String chatId;
private final String requestedUsername;
private volatile String actualUsername;
public GuestClient(String username, String chatId, Set<String> resources, Logger logger, List<ErrorHandler> errorHandlers) {
super(username, resources, logger, errorHandlers);
this.chatId = chatId;
this.requestedUsername = username;
}
@Override
public void login() throws ConnectionException, InvalidCredentialsException {
JsonObject response = Endpoints.NEW_GUEST
.open(this)
.as(JsonObject.class)
.on(303, connection -> {
throw new NotParticipatingException();
})
.expect(201, "While logging in")
.header("csrf_token", "skype4j")
.cookie("csrf_token", "skype4j")
.post(new JsonObject()
.add("name", requestedUsername)
.add("threadId", chatId)
.add("shortId", "Skype4J")
.add("flowId", "Skype4J"));
this.setSkypeToken(response.get("skypetoken").asString());
String[] splits = response.get("skypetoken").asString().split("\\.");
try {
String decoded = new String(DatatypeConverter.parseBase64Binary(Utils.makeValidBase64(splits[1])), "UTF-8");
JsonObject object = JsonObject.readFrom(decoded).asObject();
this.actualUsername = object.get("skypeid").asString();
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
List<UncheckedRunnable> tasks = new ArrayList<>();
tasks.add(() -> {
HttpURLConnection asmResponse = getAsmToken();
String[] setCookie = asmResponse.getHeaderField("Set-Cookie").split(";")[0].split("=");
this.cookies.put(setCookie[0], setCookie[1]);
});
tasks.add(this::registerEndpoint);
try {
ExecutorService executorService = Executors.newFixedThreadPool(2);
tasks.forEach(executorService::submit);
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
super.login();
}
@Override
public void logout() throws ConnectionException {
Endpoints.LEAVE_GUEST
.open(this, this.chatId)
.expect(200, "While logging out")
.cookie("guest_token_" + this.chatId, "skype4j::" + this.getSkypeToken())
.cookie("csrf_token", "skype4j")
.cookie("launcher_session_id", "Skype4J")
.get();
shutdown();
}
@Override
public GroupChat createGroupChat(Contact... contacts) {
throw new UnsupportedOperationException("Not supported with a guest account");
}
@Override
public void loadAllContacts() {
throw new UnsupportedOperationException("Not supported with a guest account");
}
@Override
public void getContactRequests(boolean fromWebsocket) {
throw new UnsupportedOperationException("Not supported with a guest account");
}
@Override
public void updateContactList() {
throw new UnsupportedOperationException("Not supported with a guest account");
}
@Override
public String getUsername() {
if (actualUsername == null) {
throw new IllegalStateException("Should not be called when login has not completed");
}
return actualUsername;
}
}