diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java b/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java index 5381a968..bae35ef7 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java @@ -9,12 +9,14 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.json.JSONObject; +import org.jsoup.nodes.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.io.HttpClient; import ctbrec.sites.cam4.Cam4LoginDialog; +import ctbrec.ui.HtmlParser; import javafx.application.Platform; import okhttp3.Cookie; import okhttp3.FormBody; @@ -25,6 +27,7 @@ import okhttp3.Response; public class CamsodaHttpClient extends HttpClient { private static final transient Logger LOG = LoggerFactory.getLogger(CamsodaHttpClient.class); + private String csrfToken = null; @Override public boolean login() throws IOException { @@ -97,6 +100,7 @@ public class CamsodaHttpClient extends HttpClient { * @throws IOException */ private boolean checkLoginSuccess() throws IOException { + // TODO load /api/v1/user/current and check status or so return true; } @@ -117,4 +121,21 @@ public class CamsodaHttpClient extends HttpClient { } cookieJar.saveFromResponse(origUrl, cookies); } + + protected String getCsrfToken() throws IOException { + if(csrfToken == null) { + String url = Camsoda.BASE_URI; + Request request = new Request.Builder().url(url).build(); + Response resp = execute(request, true); + if(resp.isSuccessful()) { + Element meta = HtmlParser.getTag(resp.body().string(), "meta[name=\"_token\"]"); + csrfToken = meta.attr("content"); + } else { + IOException e = new IOException(resp.code() + " " + resp.message()); + resp.close(); + throw e; + } + } + return csrfToken; + } } diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java b/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java index 1a6a6269..24274259 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java @@ -25,6 +25,7 @@ import ctbrec.AbstractModel; import ctbrec.recorder.download.StreamSource; import ctbrec.sites.Site; import okhttp3.Request; +import okhttp3.RequestBody; import okhttp3.Response; public class CamsodaModel extends AbstractModel { @@ -170,36 +171,50 @@ public class CamsodaModel extends AbstractModel { @Override public boolean follow() throws IOException { - // FIXME follow and unfollow don't work yet, because the HTTP requests need to have - // the cross-site scripting prevention header (e.g. X-CSRF-Token: YDixu6rFg3ovqos9C1YuYpsVd7bxuXlpNnZnelKG), - // but i didn't find out yet, how to get the token (cookie, hmac calc, ?!?) - throw new RuntimeException("Not implemented, yet"); - - // String url = Camsoda.BASE_URI + "/api/v1/follow/" + getName(); - // //RequestBody body = new FormBody.Builder().build(); - // LOG.debug("Sending follow request {}", url); - // Request request = new Request.Builder() - // .url(url) - // .post(RequestBody.create(null, "")) - // .addHeader("Referer", Camsoda.BASE_URI + '/' + getName()) - // .addHeader("User-Agent", " Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0") - // .addHeader("Accept", " application/json, text/plain, */*") - // .addHeader("Accept-Language", " de,en-US;q=0.7,en;q=0.3") - // .build(); - // Response resp = site.getHttpClient().execute(request, false); - // if (resp.isSuccessful()) { - // System.out.println(resp.body().string()); - // return true; - // } else { - // resp.close(); - // throw new IOException("HTTP status " + resp.code() + " " + resp.message()); - // } + String url = Camsoda.BASE_URI + "/api/v1/follow/" + getName(); + LOG.debug("Sending follow request {}", url); + String csrfToken = ((CamsodaHttpClient)site.getHttpClient()).getCsrfToken(); + Request request = new Request.Builder() + .url(url) + .post(RequestBody.create(null, "")) + .addHeader("Referer", Camsoda.BASE_URI + '/' + getName()) + .addHeader("User-Agent", " Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0") + .addHeader("Accept", " application/json, text/plain, */*") + .addHeader("Accept-Language", " de,en-US;q=0.7,en;q=0.3") + .addHeader("X-CSRF-Token", csrfToken) + .build(); + Response resp = site.getHttpClient().execute(request, true); + if (resp.isSuccessful()) { + resp.close(); + return true; + } else { + resp.close(); + throw new IOException("HTTP status " + resp.code() + " " + resp.message()); + } } @Override public boolean unfollow() throws IOException { - // TODO /api/v1/unfollow/" + n.slug - throw new RuntimeException("Not implemented, yet"); + String url = Camsoda.BASE_URI + "/api/v1/unfollow/" + getName(); + LOG.debug("Sending follow request {}", url); + String csrfToken = ((CamsodaHttpClient)site.getHttpClient()).getCsrfToken(); + Request request = new Request.Builder() + .url(url) + .post(RequestBody.create(null, "")) + .addHeader("Referer", Camsoda.BASE_URI + '/' + getName()) + .addHeader("User-Agent", " Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0") + .addHeader("Accept", " application/json, text/plain, */*") + .addHeader("Accept-Language", " de,en-US;q=0.7,en;q=0.3") + .addHeader("X-CSRF-Token", csrfToken) + .build(); + Response resp = site.getHttpClient().execute(request, true); + if (resp.isSuccessful()) { + resp.close(); + return true; + } else { + resp.close(); + throw new IOException("HTTP status " + resp.code() + " " + resp.message()); + } } @Override