Add electron login dialog for Chaturbate
This commit is contained in:
parent
d1c5bd4850
commit
09d9c3490e
|
@ -0,0 +1,123 @@
|
|||
package ctbrec.ui.sites.chaturbate;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.sites.chaturbate.Chaturbate;
|
||||
import ctbrec.ui.ExternalBrowser;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.Cookie.Builder;
|
||||
import okhttp3.CookieJar;
|
||||
import okhttp3.HttpUrl;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChaturbateElectronLoginDialog {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChaturbateElectronLoginDialog.class);
|
||||
public static final String DOMAIN = "chaturbate.com";
|
||||
private final Chaturbate site;
|
||||
private CookieJar cookieJar;
|
||||
private ExternalBrowser browser;
|
||||
|
||||
public ChaturbateElectronLoginDialog(Chaturbate site, CookieJar cookieJar) throws IOException {
|
||||
this.site = site;
|
||||
this.cookieJar = cookieJar;
|
||||
browser = ExternalBrowser.getInstance();
|
||||
try {
|
||||
var config = new JSONObject();
|
||||
config.put("url", site.getBaseUrl() + "/auth/login/");
|
||||
config.put("w", 640);
|
||||
config.put("h", 480);
|
||||
config.put("userAgent", Config.getInstance().getSettings().httpUserAgent);
|
||||
var msg = new JSONObject();
|
||||
msg.put("config", config);
|
||||
browser.run(msg, msgHandler);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Couldn't wait for login dialog", e);
|
||||
} finally {
|
||||
browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
private final Consumer<String> msgHandler = line -> {
|
||||
if (!line.startsWith("{")) {
|
||||
LOG.error("Didn't received a JSON object {}", line);
|
||||
} else {
|
||||
var json = new JSONObject(line);
|
||||
if (json.has("url")) {
|
||||
var url = json.getString("url");
|
||||
if (url.endsWith("/auth/login/")) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
String username = Config.getInstance().getSettings().chaturbateUsername;
|
||||
if (username != null && !username.trim().isEmpty()) {
|
||||
browser.executeJavaScript("document.getElementById('id_username').value = '" + username + "'");
|
||||
}
|
||||
String password = Config.getInstance().getSettings().chaturbatePassword;
|
||||
if (password != null && !password.trim().isEmpty()) {
|
||||
password = password.replace("'", "\\'");
|
||||
browser.executeJavaScript("document.getElementById('id_password').value = '" + password + "'");
|
||||
}
|
||||
var simplify = new String[]{
|
||||
"$('div#header').css('display','none');",
|
||||
"$('div#footer-holder').css('display','none')",
|
||||
};
|
||||
for (String js : simplify) {
|
||||
browser.executeJavaScript(js);
|
||||
}
|
||||
browser.executeJavaScript("document.querySelector('form[action*=login]').submit()");
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.warn("Couldn't auto fill username and password for Chaturbate", e);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Couldn't auto fill username and password for Chaturbate", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (json.has("cookies")) {
|
||||
var cookiesFromBrowser = json.getJSONArray("cookies");
|
||||
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
|
||||
var cookie = cookiesFromBrowser.getJSONObject(i);
|
||||
if (cookie.getString("domain").contains(DOMAIN)) {
|
||||
Builder b = new Builder()
|
||||
.path(cookie.getString("path"))
|
||||
.domain(DOMAIN)
|
||||
.name(cookie.getString("name"))
|
||||
.value(cookie.getString("value"))
|
||||
.expiresAt((long) cookie.optDouble("expirationDate"));
|
||||
if (cookie.optBoolean("hostOnly")) {
|
||||
b.hostOnlyDomain(DOMAIN);
|
||||
}
|
||||
if (cookie.optBoolean("httpOnly")) {
|
||||
b.httpOnly();
|
||||
}
|
||||
if (cookie.optBoolean("secure")) {
|
||||
b.secure();
|
||||
}
|
||||
Cookie c = b.build();
|
||||
cookieJar.saveFromResponse(HttpUrl.parse(ChaturbateElectronLoginDialog.this.site.getBaseUrl()), Collections.singletonList(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (Objects.equals(new URL(url).getPath(), "/")) {
|
||||
browser.close();
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
LOG.error("Couldn't parse new url {}", url, e);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Couldn't send shutdown request to external browser", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,14 +1,20 @@
|
|||
package ctbrec.ui.sites.chaturbate;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ctbrec.sites.chaturbate.Chaturbate;
|
||||
import ctbrec.sites.chaturbate.ChaturbateHttpClient;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.sites.AbstractSiteUi;
|
||||
import ctbrec.ui.sites.ConfigUI;
|
||||
import ctbrec.ui.tabs.TabProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ChaturbateSiteUi extends AbstractSiteUi {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChaturbateSiteUi.class);
|
||||
|
||||
private final Chaturbate chaturbate;
|
||||
private ChaturbateTabProvider tabProvider;
|
||||
private ChaturbateConfigUi configUi;
|
||||
|
@ -35,7 +41,26 @@ public class ChaturbateSiteUi extends AbstractSiteUi {
|
|||
|
||||
@Override
|
||||
public synchronized boolean login() throws IOException {
|
||||
return chaturbate.login();
|
||||
boolean automaticLogin = false;
|
||||
try {
|
||||
automaticLogin = chaturbate.login();
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Automatic login failed", e);
|
||||
}
|
||||
if (automaticLogin) {
|
||||
return true;
|
||||
} else {
|
||||
// login with external browser window
|
||||
try {
|
||||
new ChaturbateElectronLoginDialog(chaturbate, chaturbate.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + chaturbate.getName(), e1);
|
||||
}
|
||||
|
||||
ChaturbateHttpClient httpClient = (ChaturbateHttpClient) chaturbate.getHttpClient();
|
||||
return httpClient.checkLogin();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
package ctbrec.sites.chaturbate;
|
||||
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import ctbrec.Config;
|
||||
import ctbrec.io.HtmlParser;
|
||||
import ctbrec.io.HttpClient;
|
||||
import okhttp3.*;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
|
@ -8,25 +14,16 @@ import java.util.NoSuchElementException;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.io.HtmlParser;
|
||||
import ctbrec.io.HttpClient;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import static ctbrec.io.HttpConstants.REFERER;
|
||||
import static ctbrec.io.HttpConstants.USER_AGENT;
|
||||
|
||||
public class ChaturbateHttpClient extends HttpClient {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChaturbateHttpClient.class);
|
||||
private static final String PATH = "/auth/login/"; // NOSONAR
|
||||
protected String token;
|
||||
|
||||
private static Semaphore requestThrottle = new Semaphore(2, true);
|
||||
private static final Semaphore requestThrottle = new Semaphore(2, true);
|
||||
private static long lastRequest = 0;
|
||||
|
||||
public ChaturbateHttpClient(Config config) {
|
||||
|
@ -37,13 +34,13 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
try {
|
||||
Cookie csrfToken = cookieJar.getCookie(request.url(), "csrftoken");
|
||||
token = csrfToken.value();
|
||||
} catch(NoSuchElementException e) {
|
||||
} catch (NoSuchElementException e) {
|
||||
LOG.trace("CSRF token not found in cookies");
|
||||
}
|
||||
}
|
||||
|
||||
public String getToken() throws IOException {
|
||||
if(token == null) {
|
||||
if (token == null) {
|
||||
login();
|
||||
}
|
||||
return token;
|
||||
|
@ -51,11 +48,11 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
|
||||
@Override
|
||||
public boolean login() throws IOException {
|
||||
if(loggedIn) {
|
||||
if (loggedIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(checkLogin()) {
|
||||
if (checkLogin()) {
|
||||
loggedIn = true;
|
||||
LOG.debug("Logged in with cookies");
|
||||
return true;
|
||||
|
@ -63,7 +60,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
|
||||
try {
|
||||
Request login = new Request.Builder()
|
||||
.url(Chaturbate.baseUrl + "/auth/login/")
|
||||
.url(Chaturbate.baseUrl + PATH)
|
||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||
.build();
|
||||
Response response = client.newCall(login).execute();
|
||||
|
@ -78,23 +75,23 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
.add("csrfmiddlewaretoken", token)
|
||||
.build();
|
||||
login = new Request.Builder()
|
||||
.url(Chaturbate.baseUrl + "/auth/login/")
|
||||
.header(REFERER, Chaturbate.baseUrl + "/auth/login/")
|
||||
.url(Chaturbate.baseUrl + PATH)
|
||||
.header(REFERER, Chaturbate.baseUrl + PATH)
|
||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
response = client.newCall(login).execute();
|
||||
if(response.isSuccessful()) {
|
||||
if (response.isSuccessful()) {
|
||||
content = response.body().string();
|
||||
if(content.contains("Login, Chaturbate login")) {
|
||||
if (content.contains("Login, Chaturbate login")) {
|
||||
loggedIn = false;
|
||||
} else {
|
||||
loggedIn = true;
|
||||
extractCsrfToken(login);
|
||||
}
|
||||
} else {
|
||||
if(loginTries++ < 3) {
|
||||
if (loginTries++ < 3) {
|
||||
login();
|
||||
} else {
|
||||
throw new IOException("Login failed: " + response.code() + " " + response.message());
|
||||
|
@ -107,24 +104,25 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
return loggedIn;
|
||||
}
|
||||
|
||||
private boolean checkLogin() throws IOException {
|
||||
public boolean checkLogin() throws IOException {
|
||||
String url = "https://chaturbate.com/p/" + Config.getInstance().getSettings().chaturbateUsername + "/";
|
||||
Request req = new Request.Builder()
|
||||
.url(url)
|
||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||
.build();
|
||||
Response resp = execute(req);
|
||||
if (resp.isSuccessful()) {
|
||||
String profilePage = resp.body().string();
|
||||
try {
|
||||
Element userIcon = HtmlParser.getTag(profilePage, "img.user_information_header_icon");
|
||||
return !Objects.equals("Anonymous Icon", userIcon.attr("alt"));
|
||||
} catch(Exception e) {
|
||||
LOG.debug("Token tag not found. Login failed");
|
||||
return false;
|
||||
try (Response resp = execute(req)) {
|
||||
if (resp.isSuccessful()) {
|
||||
String profilePage = resp.body().string();
|
||||
try {
|
||||
Element userIcon = HtmlParser.getTag(profilePage, "img.user_information_header_icon");
|
||||
return !Objects.equals("Anonymous Icon", userIcon.attr("alt"));
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Token tag not found. Login failed");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
throw new IOException("HTTP response: " + resp.code() + " - " + resp.message());
|
||||
}
|
||||
} else {
|
||||
throw new IOException("HTTP response: " + resp.code() + " - " + resp.message());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue