1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 00:39:08 -05:00

[API] Make support for alternative log addresses more centralized (#52)

This commit is contained in:
Mikołaj Pich 2018-02-26 20:36:45 +01:00 committed by Rafał Borcz
parent f93816910d
commit a1a3427142
12 changed files with 164 additions and 175 deletions

View File

@ -9,22 +9,41 @@ import java.util.Map;
public class Client {
private String protocol;
private String host;
private String symbol;
private Cookies cookies = new Cookies();
Cookies getCookiesObject() {
return cookies;
Client(String protocol, String host, String symbol) {
this.protocol = protocol;
this.host = host;
this.symbol = symbol;
}
void setCookies(Cookies cookies) {
this.cookies = cookies;
String getHost() {
return host;
}
Map<String, String> getCookies() {
public void setSymbol(String symbol) {
this.symbol = symbol;
}
Map<String, String> getCookies() {
return cookies.getItems();
}
public Document getPageByUrl(String url) throws IOException {
Connection.Response response = Jsoup.connect(url)
private String getFilledUrl(String url) {
return url
.replace("{schema}", protocol)
.replace("{host}", host.replace(":", "%253A"))
.replace("{symbol}", symbol == null ? "Default" : symbol);
}
Document getPageByUrl(String url) throws IOException {
Connection.Response response = Jsoup.connect(getFilledUrl(url))
.followRedirects(true)
.cookies(getCookies())
.execute();
@ -35,7 +54,7 @@ public class Client {
}
public Document postPageByUrl(String url, String[][] params) throws IOException {
Connection connection = Jsoup.connect(url);
Connection connection = Jsoup.connect(getFilledUrl(url));
for (String[] data : params) {
connection.data(data[0], data[1]);
@ -53,7 +72,7 @@ public class Client {
}
public String getJsonStringByUrl(String url) throws IOException {
Connection.Response response = Jsoup.connect(url)
Connection.Response response = Jsoup.connect(getFilledUrl(url))
.followRedirects(true)
.ignoreContentType(true)
.cookies(getCookies())
@ -65,7 +84,7 @@ public class Client {
}
public String postJsonStringByUrl(String url, String[][] params) throws IOException {
Connection connection = Jsoup.connect(url);
Connection connection = Jsoup.connect(getFilledUrl(url));
for (String[] data : params) {
connection.data(data[0], data[1]);

View File

@ -10,14 +10,6 @@ import io.github.wulkanowy.api.login.NotLoggedInErrorException;
public interface SnP {
void setProtocolSchema(String schema);
String getLogHost();
void setLogHost(String hostname);
String getSymbol();
String getId();
void storeContextCookies() throws IOException, NotLoggedInErrorException;

View File

@ -12,67 +12,27 @@ import io.github.wulkanowy.api.login.NotLoggedInErrorException;
public class StudentAndParent implements SnP {
private static final String startPageUrl = "{schema}://uonetplus.{host}/{symbol}/Start.mvc/Index";
private static final String START_PAGE_URL = "{schema}://uonetplus.{host}/{symbol}/Start.mvc/Index";
private static final String baseUrl = "{schema}://uonetplus-opiekun.{host}/{symbol}/{ID}/";
private static final String SYMBOL_PLACEHOLDER = "{symbol}";
private static final String BASE_URL = "{schema}://uonetplus-opiekun.{host}/{symbol}/{ID}/";
private static final String GRADES_PAGE_URL = "Oceny/Wszystkie";
private Client client;
private String logHost = "vulcan.net.pl";
private String protocolSchema = "https";
private String symbol;
private String id;
public StudentAndParent(Client client, String symbol) {
StudentAndParent(Client client) {
this.client = client;
this.symbol = symbol;
}
public StudentAndParent(Client client, String symbol, String id) {
this(client, symbol);
StudentAndParent(Client client, String id) {
this(client);
this.id = id;
}
public void setProtocolSchema(String schema) {
this.protocolSchema = schema;
}
public String getLogHost() {
return logHost;
}
public void setLogHost(String hostname) {
this.logHost = hostname;
}
public String getStartPageUrl() {
return startPageUrl
.replace("{schema}", protocolSchema)
.replace("{host}", logHost)
.replace(SYMBOL_PLACEHOLDER, getSymbol());
}
public String getBaseUrl() {
return baseUrl
.replace("{schema}", protocolSchema)
.replace("{host}", logHost)
.replace(SYMBOL_PLACEHOLDER, getSymbol())
.replace("{ID}", getId());
}
public String getGradesPageUrl() {
return getBaseUrl() + GRADES_PAGE_URL;
}
public String getSymbol() {
return symbol;
private String getBaseUrl() {
return BASE_URL.replace("{ID}", getId());
}
public String getId() {
@ -80,16 +40,16 @@ public class StudentAndParent implements SnP {
}
public void storeContextCookies() throws IOException, NotLoggedInErrorException {
client.getPageByUrl(getSnpPageUrl());
client.getPageByUrl(getSnpHomePageUrl());
}
public String getSnpPageUrl() throws IOException, NotLoggedInErrorException {
String getSnpHomePageUrl() throws IOException, NotLoggedInErrorException {
if (null != getId()) {
return getBaseUrl();
}
// get url to uonetplus-opiekun.vulcan.net.pl
Document startPage = client.getPageByUrl(getStartPageUrl());
Document startPage = client.getPageByUrl(START_PAGE_URL);
Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first();
if (null == studentTileLink) {
@ -103,14 +63,14 @@ public class StudentAndParent implements SnP {
return snpPageUrl;
}
public String getExtractedIdFromUrl(String snpPageUrl) throws NotLoggedInErrorException {
String[] path = snpPageUrl.split(getLogHost() + "/")[1].split("/");
String getExtractedIdFromUrl(String snpPageUrl) throws NotLoggedInErrorException {
String[] path = snpPageUrl.split(client.getHost())[1].split("/");
if (4 != path.length) {
if (5 != path.length) {
throw new NotLoggedInErrorException();
}
return path[1];
return path[2];
}
public String getRowDataChildValue(Element e, int index) {
@ -118,13 +78,11 @@ public class StudentAndParent implements SnP {
}
public Document getSnPPageDocument(String url) throws IOException {
return client.getPageByUrl(getBaseUrl()
.replace(SYMBOL_PLACEHOLDER, getSymbol())
.replace("{ID}", getId()) + url);
return client.getPageByUrl(getBaseUrl() + url);
}
public List<Semester> getSemesters() throws IOException {
return getSemesters(getSnPPageDocument(getGradesPageUrl()));
return getSemesters(getSnPPageDocument(GRADES_PAGE_URL));
}
public List<Semester> getSemesters(Document gradesPage) {

View File

@ -36,9 +36,9 @@ public class Vulcan {
private String email;
private Client client = new Client();
private Client client;
private Login login = new Login(client);
private Login login;
public void setClient(Client client) {
this.client = client;
@ -48,17 +48,16 @@ public class Vulcan {
this.login = login;
}
public Vulcan login(String email, String password, String symbol)
public String login(String email, String password, String symbol)
throws BadCredentialsException, AccountPermissionException,
LoginErrorException, IOException, VulcanOfflineException {
setFullEndpointInfo(email);
login.setProtocolSchema(protocolSchema);
login.setLogHost(logHost);
login = getLogin();
this.symbol = login.login(this.email, password, symbol);
return this;
return this.symbol;
}
public Vulcan login(String email, String password, String symbol, String id)
@ -71,11 +70,11 @@ public class Vulcan {
return this;
}
public String getProtocolSchema() {
String getProtocolSchema() {
return protocolSchema;
}
public String getLogHost() {
String getLogHost() {
return logHost;
}
@ -97,8 +96,28 @@ public class Vulcan {
}
}
protected Client getClient() {
if (null != client) {
return client;
}
client = new Client(getProtocolSchema(), getLogHost(), symbol);
return client;
}
protected Login getLogin() {
if (null != login) {
return login;
}
login = new Login(getClient());
return login;
}
public SnP getStudentAndParent() throws IOException, NotLoggedInErrorException {
if (0 == client.getCookies().size()) {
if (0 == getClient().getCookies().size()) {
throw new NotLoggedInErrorException();
}
@ -106,21 +125,19 @@ public class Vulcan {
return snp;
}
snp = createSnp(client, symbol, id);
snp.setLogHost(logHost);
snp.setProtocolSchema(protocolSchema);
snp = createSnp(getClient(), id);
snp.storeContextCookies();
return snp;
}
SnP createSnp(Client client, String symbol, String id) {
SnP createSnp(Client client, String id) {
if (null == id) {
return new StudentAndParent(client, symbol);
return new StudentAndParent(client);
}
return new StudentAndParent(client, symbol, id);
return new StudentAndParent(client, id);
}
public AttendanceStatistics getAttendanceStatistics() throws IOException, NotLoggedInErrorException {
@ -172,6 +189,6 @@ public class Vulcan {
}
public Messages getMessages() {
return new Messages(client, getProtocolSchema(), getLogHost(), symbol);
return new Messages(getClient());
}
}

View File

@ -6,53 +6,33 @@ import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.regex.Pattern;
import io.github.wulkanowy.api.Client;
public class Login {
private static final String loginPageUrl = "{schema}://cufs.{host}/{symbol}/Account/LogOn" +
private static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn" +
"?ReturnUrl=%2F{symbol}%2FFS%2FLS%3Fwa%3Dwsignin1.0%26wtrealm%3D" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx%26wctx%3D" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx";
private static final String loginEndpointPageUrl =
private static final String LOGIN_ENDPOINT_PAGE_URL =
"{schema}://uonetplus.{host}/{symbol}/LoginEndpoint.aspx";
private String protocolSchema = "https";
private String logHost = "vulcan.net.pl";
private String symbol = "Default";
private Client client;
private String symbol;
public Login(Client client) {
this.client = client;
}
public void setProtocolSchema(String schema) {
this.protocolSchema = schema;
private String getLoginPageUrl() {
return LOGIN_PAGE_URL;
}
public void setLogHost(String hostname) {
this.logHost = hostname;
}
public String getLoginPageUrl() {
return loginPageUrl
.replace("{schema}", protocolSchema)
.replaceFirst(Pattern.quote("{host}"), logHost)
.replace("{host}", logHost.replace(":", "%253A"))
.replace("{symbol}", symbol);
}
public String getLoginEndpointPageUrl() {
return loginEndpointPageUrl
.replace("{schema}", protocolSchema)
.replace("{host}", logHost)
.replace("{symbol}", symbol);
private String getLoginEndpointPageUrl() {
return LOGIN_ENDPOINT_PAGE_URL;
}
public String login(String email, String password, String symbol)
@ -63,7 +43,7 @@ public class Login {
return sendCertificate(certificate, symbol);
}
public String sendCredentials(String email, String password, String symbol)
String sendCredentials(String email, String password, String symbol)
throws IOException, BadCredentialsException {
this.symbol = symbol;
@ -79,11 +59,13 @@ public class Login {
return html.select("input[name=wresult]").attr("value");
}
public String sendCertificate(String certificate, String defaultSymbol)
String sendCertificate(String certificate, String defaultSymbol)
throws IOException, LoginErrorException, AccountPermissionException, VulcanOfflineException {
this.symbol = findSymbol(defaultSymbol, certificate);
client.setSymbol(this.symbol);
Document html = client.postPageByUrl(getLoginEndpointPageUrl(), new String[][]{
Document html = client.postPageByUrl(getLoginEndpointPageUrl()
.replace("{symbol}", this.symbol), new String[][]{
{"wa", "wsignin1.0"},
{"wresult", certificate}
});
@ -103,7 +85,7 @@ public class Login {
return this.symbol;
}
public String findSymbol(String symbol, String certificate) {
private String findSymbol(String symbol, String certificate) {
if ("Default".equals(symbol)) {
return findSymbolInCertificate(certificate);
}
@ -111,7 +93,7 @@ public class Login {
return symbol;
}
public String findSymbolInCertificate(String certificate) {
String findSymbolInCertificate(String certificate) {
Elements els = Jsoup.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
.select("[AttributeName=\"UserInstance\"] samlAttributeValue");

View File

@ -1,5 +1,4 @@
package io.github.wulkanowy.api.login;
public class NotLoggedInErrorException extends Exception {
}

View File

@ -33,23 +33,8 @@ public class Messages {
private Client client;
private String schema;
private String host;
private String symbol;
public Messages(Client client, String schema, String host, String symbol) {
public Messages(Client client) {
this.client = client;
this.schema = schema;
this.host = host;
this.symbol = symbol;
}
private String getFilledUrl(String url) {
return url.replace("{schema}", schema)
.replace("{host}", host)
.replace("{symbol}", symbol);
}
public List<Message> getReceived() throws IOException, NotLoggedInErrorException, BadRequestException {
@ -65,7 +50,7 @@ public class Messages {
}
private List<Message> getMessages(String url) throws IOException, NotLoggedInErrorException, BadRequestException {
String res = client.getJsonStringByUrl(getFilledUrl(url));
String res = client.getJsonStringByUrl(url);
List<Message> messages;
@ -103,11 +88,11 @@ public class Messages {
return message;
}
public static class MessagesContainer {
public List<Message> data;
private static class MessagesContainer {
private List<Message> data;
}
public static class MessageContainer {
public Message data;
private static class MessageContainer {
private Message data;
}
}

View File

@ -28,15 +28,14 @@ public class StudentAndParentTest {
@Test
public void snpTest() throws Exception {
StudentAndParent snp = new StudentAndParent(client, "demo123", "id123");
Assert.assertEquals("demo123", snp.getSymbol());
StudentAndParent snp = new StudentAndParent(client, "id123");
Assert.assertEquals("id123", snp.getId());
}
@Test
public void getSnpPageUrlWithIdTest() throws Exception {
Assert.assertEquals("https://uonetplus-opiekun.vulcan.net.pl/symbol/123456/",
(new StudentAndParent(client, "symbol", "123456")).getSnpPageUrl());
Assert.assertEquals("{schema}://uonetplus-opiekun.{host}/{symbol}/123456/",
(new StudentAndParent(client, "123456")).getSnpHomePageUrl());
}
@Test
@ -44,11 +43,12 @@ public class StudentAndParentTest {
String input = FixtureHelper.getAsString(getClass().getResourceAsStream("Start.html"));
Document startPageDocument = Jsoup.parse(input);
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(startPageDocument);
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client);
Assert.assertEquals("https://uonetplus-opiekun.vulcan.net.pl/symbol/534213/Start/Index/",
snp.getSnpPageUrl());
snp.getSnpHomePageUrl());
}
@Test(expected = NotLoggedInErrorException.class)
@ -58,13 +58,14 @@ public class StudentAndParentTest {
);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(wrongPageDocument);
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client);
snp.getSnpPageUrl();
snp.getSnpHomePageUrl();
}
@Test
public void getExtractedIDStandardTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
Assert.assertEquals("123456", snp.getExtractedIdFromUrl("https://uonetplus-opiekun"
+ ".vulcan.net.pl/powiat/123456/Start/Index/"));
@ -72,21 +73,23 @@ public class StudentAndParentTest {
@Test
public void getExtractedIDDemoTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
Assert.assertEquals("demo12345", snp.getExtractedIdFromUrl("https://uonetplus-opiekundemo"
+ ".vulcan.net.pl/demoupowiat/demo12345/Start/Index/"));
Assert.assertEquals("demo12345",
snp.getExtractedIdFromUrl("https://uonetplus-opiekun.vulcan.net.pl/demoupowiat/demo12345/Start/Index/"));
}
@Test(expected = NotLoggedInErrorException.class)
public void getExtractedIDNotLoggedTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
Assert.assertEquals("123", snp.getExtractedIdFromUrl("https://uonetplus"
+ ".vulcan.net.pl/powiat/"));
Assert.assertEquals("123",
snp.getExtractedIdFromUrl("https://uonetplus.vulcan.net.pl/powiat/"));
}
@Test
public void getSemestersTest() throws Exception {
SnP snp = new StudentAndParent(client, "symbol", "123456");
SnP snp = new StudentAndParent(client, "123456");
List<Semester> semesters = snp.getSemesters();
Assert.assertEquals(2, semesters.size());

View File

@ -5,6 +5,9 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.HashMap;
import java.util.Map;
import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
@ -28,20 +31,51 @@ public class VulcanTest {
Assert.assertEquals("admin", vulcan.getEmail());
}
@Test
public void getClientTwiceTest() throws Exception {
Vulcan vulcan = new Vulcan();
Assert.assertTrue(vulcan.getClient().equals(vulcan.getClient()));
}
@Test
public void getLoginTwiceTest() throws Exception {
Vulcan vulcan = new Vulcan();
Assert.assertTrue(vulcan.getLogin().equals(vulcan.getLogin()));
}
@Test(expected = NotLoggedInErrorException.class)
public void getStudentAndParentNotLoggedInTest() throws Exception {
vulcan.getStudentAndParent();
}
@Test
public void getStudentAndParentTwiceTest() throws Exception {
Client client = Mockito.mock(Client.class);
Map<String, String> cookies = new HashMap<>();
cookies.put("test", "test");
Mockito.when(client.getCookies()).thenReturn(cookies);
SnP snp = Mockito.mock(StudentAndParent.class);
Mockito.doNothing().when(snp).storeContextCookies();
Vulcan vulcan = Mockito.mock(Vulcan.class);
Mockito.when(vulcan.getClient()).thenReturn(client);
Mockito.when(vulcan.getStudentAndParent()).thenCallRealMethod();
Mockito.when(vulcan.createSnp(Mockito.any(Client.class), Mockito.any())).thenReturn(snp);
vulcan.getStudentAndParent();
vulcan.getStudentAndParent();
}
@Test
public void createSnPTest() throws Exception {
vulcan.login("wulkanowy@wulkanowy.io", "wulkanowy123", "wulkan");
SnP snp1 = vulcan.createSnp(Mockito.mock(Client.class), "testSymbol", null);
Assert.assertEquals(snp1.getId(), null);
SnP snp1 = vulcan.createSnp(Mockito.mock(Client.class), null);
Assert.assertEquals(null, snp1.getId());
SnP snp2 = vulcan.createSnp(Mockito.mock(Client.class), "testSymbol", "wulkan");
Assert.assertEquals(snp2.getId(), "wulkan");
SnP snp2 = vulcan.createSnp(Mockito.mock(Client.class), "wulkan");
Assert.assertEquals("wulkan", snp2.getId());
}

View File

@ -25,7 +25,7 @@ public class MessagesTest {
public void getMessages() throws Exception {
Client client = getFixtureAsString("GetWiadomosciOdebrane.json");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
List<Message> messageList = messages.getReceived();
Assert.assertEquals(true, messageList.get(1).unread);
@ -39,7 +39,7 @@ public class MessagesTest {
public void getMessagesEmpty() throws Exception {
Client client = getFixtureAsString("GetWiadomosciUsuniete-empty.json");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
List<Message> messageList = messages.getSent();
Assert.assertTrue(messageList.isEmpty());
@ -49,7 +49,7 @@ public class MessagesTest {
public void getMessagesError() throws Exception {
Client client = getFixtureAsString("UndefinedError.txt");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
messages.getDeleted();
}
@ -57,7 +57,7 @@ public class MessagesTest {
public void getMessagesBadRequest() throws Exception {
Client client = getFixtureAsString("PageError.html");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
messages.getDeleted();
}
@ -65,7 +65,7 @@ public class MessagesTest {
public void getMessage() throws Exception {
Client client = getFixtureAsString("GetTrescWiadomosci.json");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
Message message = messages.getMessage(123, Messages.RECEIVED_FOLDER);
Assert.assertEquals(12345, message.id);
Assert.assertEquals("Witam, …. \nPozdrawiam Krzysztof Czerkas", message.content);
@ -75,7 +75,7 @@ public class MessagesTest {
public void getMessageError() throws Exception {
Client client = getFixtureAsString("UndefinedError.txt");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
messages.getMessage(321, Messages.SENT_FOLDER);
}
@ -83,7 +83,7 @@ public class MessagesTest {
public void getMessageBadRequest() throws Exception {
Client client = getFixtureAsString("PageError.html");
Messages messages = new Messages(client, "", "", "");
Messages messages = new Messages(client);
messages.getMessage(1, Messages.DELETED_FOLDER);
}
}

View File

@ -50,7 +50,6 @@ public class FirstAccountLoginTest {
@Test
public void loginTest() throws Exception {
StudentAndParent snp = Mockito.mock(StudentAndParent.class);
Mockito.when(snp.getSymbol()).thenReturn("TEST-SYMBOL");
Mockito.when(snp.getId()).thenReturn("TEST-ID");
PersonalData personalData = Mockito.mock(PersonalData.class);
@ -60,8 +59,9 @@ public class FirstAccountLoginTest {
Mockito.doReturn(personalData).when(basicInformation).getPersonalData();
Vulcan vulcan = Mockito.mock(Vulcan.class);
Mockito.doReturn(basicInformation).when(vulcan).getBasicInformation();
Mockito.doReturn("TEST-SYMBOL").when(vulcan).login(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
Mockito.doReturn(snp).when(vulcan).getStudentAndParent();
Mockito.doReturn(basicInformation).when(vulcan).getBasicInformation();
FirstAccountLogin firstAccountLogin = new FirstAccountLogin(targetContext, daoSession, vulcan);
LoginSession loginSession = firstAccountLogin.login("TEST@TEST", "TEST-PASS", "default");

View File

@ -33,7 +33,7 @@ public class FirstAccountLogin {
public LoginSession login(String email, String password, String symbol)
throws NotLoggedInErrorException, AccountPermissionException, IOException, CryptoException, VulcanOfflineException, BadCredentialsException {
vulcan.login(email, password, symbol);
String realSymbol = vulcan.login(email, password, symbol);
AccountDao accountDao = daoSession.getAccountDao();
Safety safety = new Safety();
@ -41,7 +41,7 @@ public class FirstAccountLogin {
.setName(vulcan.getBasicInformation().getPersonalData().getFirstAndLastName())
.setEmail(email)
.setPassword(safety.encrypt(email, password, context))
.setSymbol(vulcan.getStudentAndParent().getSymbol())
.setSymbol(realSymbol)
.setSnpId(vulcan.getStudentAndParent().getId());
long userId = accountDao.insert(account);