forked from github/wulkanowy-mirror
[API] Fix first login (#107)
This commit is contained in:
parent
2cf262130e
commit
cd6e14b13b
@ -23,7 +23,7 @@ public class Client {
|
|||||||
|
|
||||||
private String symbol;
|
private String symbol;
|
||||||
|
|
||||||
private Date lastSuccessRequest = null;
|
private Date lastSuccessRequest;
|
||||||
|
|
||||||
private Cookies cookies = new Cookies();
|
private Cookies cookies = new Cookies();
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ public class Client {
|
|||||||
return getPageByUrl(url, loginBefore, null);
|
return getPageByUrl(url, loginBefore, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Document getPageByUrl(String url, boolean loginBefore, Map<String, String> cookies) throws IOException, VulcanException {
|
public synchronized Document getPageByUrl(String url, boolean loginBefore, Map<String, String> cookies) throws IOException, VulcanException {
|
||||||
if (loginBefore) {
|
if (loginBefore) {
|
||||||
login();
|
login();
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ public class Client {
|
|||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException {
|
public synchronized Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException {
|
||||||
Connection connection = Jsoup.connect(getFilledUrl(url));
|
Connection connection = Jsoup.connect(getFilledUrl(url));
|
||||||
|
|
||||||
for (String[] data : params) {
|
for (String[] data : params) {
|
||||||
|
@ -106,7 +106,11 @@ public class StudentAndParent implements SnP {
|
|||||||
|
|
||||||
Document doc = client.getPageByUrl(getBaseUrl() + url, true, cookies);
|
Document doc = client.getPageByUrl(getBaseUrl() + url, true, cookies);
|
||||||
|
|
||||||
if ("Witryna ucznia i rodzica – Strona główna".equals(doc.select("title").first().text())) {
|
if (!doc.title().startsWith("Witryna ucznia i rodzica")) {
|
||||||
|
throw new VulcanException("Expected SnP page, got page with title: " + doc.title());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.title().endsWith("Strona główna")) {
|
||||||
throw new VulcanException("Sesja została nieprawidłowo zainicjowana");
|
throw new VulcanException("Sesja została nieprawidłowo zainicjowana");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import io.github.wulkanowy.api.VulcanException;
|
|||||||
|
|
||||||
public class Login {
|
public class Login {
|
||||||
|
|
||||||
private static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn" +
|
static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn" +
|
||||||
"?ReturnUrl=%2F{symbol}%2FFS%2FLS%3Fwa%3Dwsignin1.0%26wtrealm%3D" +
|
"?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%26wctx%3D" +
|
||||||
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx";
|
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx";
|
||||||
@ -47,6 +47,8 @@ public class Login {
|
|||||||
);
|
);
|
||||||
credentials = getFormStateParams(formSecond, email, password);
|
credentials = getFormStateParams(formSecond, email, password);
|
||||||
nextUrl = formSecond.select("#form1").first().attr("abs:action");
|
nextUrl = formSecond.select("#form1").first().attr("abs:action");
|
||||||
|
} else if (!"Logowanie".equals(loginPage.select("#h1Default").text())) {
|
||||||
|
throw new VulcanException("Expected login page, got page with title: " + loginPage.title());
|
||||||
}
|
}
|
||||||
|
|
||||||
Document html = client.postPageByUrl(nextUrl, credentials);
|
Document html = client.postPageByUrl(nextUrl, credentials);
|
||||||
@ -77,14 +79,17 @@ public class Login {
|
|||||||
String sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException {
|
String sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException {
|
||||||
String certificate = doc.select("input[name=wresult]").val();
|
String certificate = doc.select("input[name=wresult]").val();
|
||||||
|
|
||||||
String symbol = findSymbol(defaultSymbol, certificate);
|
if ("".equals(certificate)) {
|
||||||
client.setSymbol(symbol);
|
throw new VulcanException("Expected certificate, got empty string. Page title: " + doc.title());
|
||||||
|
}
|
||||||
|
|
||||||
|
client.setSymbol(findSymbol(defaultSymbol, certificate));
|
||||||
|
|
||||||
Document targetDoc = sendCertData(doc);
|
Document targetDoc = sendCertData(doc);
|
||||||
String title = targetDoc.select("title").text();
|
String title = targetDoc.title();
|
||||||
|
|
||||||
if ("Working...".equals(title)) { // on adfs login
|
if ("Working...".equals(title)) { // on adfs login
|
||||||
title = sendCertData(targetDoc).select("title").text();
|
title = sendCertData(targetDoc).title();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Logowanie".equals(title)) {
|
if ("Logowanie".equals(title)) {
|
||||||
@ -95,12 +100,16 @@ public class Login {
|
|||||||
throw new LoginErrorException("Expected page title `UONET+`, got " + title);
|
throw new LoginErrorException("Expected page title `UONET+`, got " + title);
|
||||||
}
|
}
|
||||||
|
|
||||||
return symbol;
|
return client.getSymbol();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Document sendCertData(Document doc) throws IOException, VulcanException {
|
private Document sendCertData(Document doc) throws IOException, VulcanException {
|
||||||
String url = doc.select("form[name=hiddenform]").attr("action");
|
String url = doc.select("form[name=hiddenform]").attr("action");
|
||||||
|
|
||||||
|
if (!doc.title().equals("Working...")) {
|
||||||
|
throw new VulcanException("Expected certificate page, got page with title: " + doc.title());
|
||||||
|
}
|
||||||
|
|
||||||
return client.postPageByUrl(url.replaceFirst("Default", "{symbol}"), new String[][]{
|
return client.postPageByUrl(url.replaceFirst("Default", "{symbol}"), new String[][]{
|
||||||
{"wa", "wsignin1.0"},
|
{"wa", "wsignin1.0"},
|
||||||
{"wresult", doc.select("input[name=wresult]").val()},
|
{"wresult", doc.select("input[name=wresult]").val()},
|
||||||
@ -108,7 +117,7 @@ public class Login {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private String findSymbol(String symbol, String certificate) {
|
private String findSymbol(String symbol, String certificate) throws AccountPermissionException {
|
||||||
if ("Default".equals(symbol)) {
|
if ("Default".equals(symbol)) {
|
||||||
return findSymbolInCertificate(certificate);
|
return findSymbolInCertificate(certificate);
|
||||||
}
|
}
|
||||||
@ -116,13 +125,13 @@ public class Login {
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
String findSymbolInCertificate(String certificate) {
|
String findSymbolInCertificate(String certificate) throws AccountPermissionException {
|
||||||
Elements instances = Jsoup
|
Elements instances = Jsoup
|
||||||
.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
|
.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
|
||||||
.select("[AttributeName=\"UserInstance\"] samlAttributeValue");
|
.select("[AttributeName=\"UserInstance\"] samlAttributeValue");
|
||||||
|
|
||||||
if (instances.isEmpty()) {
|
if (instances.size() < 2) { // 1st index is always `Default`
|
||||||
return "";
|
throw new AccountPermissionException("First login detected, specify symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
return instances.get(1).text();
|
return instances.get(1).text();
|
||||||
|
@ -34,6 +34,10 @@ public class LoginTest {
|
|||||||
Client client = getClient("Logowanie-success.html");
|
Client client = getClient("Logowanie-success.html");
|
||||||
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
|
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
|
||||||
.thenReturn(getFixtureAsDocument("Logowanie-error.html"));
|
.thenReturn(getFixtureAsDocument("Logowanie-error.html"));
|
||||||
|
Mockito.when(client.postPageByUrl(Mockito.eq(Login.LOGIN_PAGE_URL), Mockito.any(String[][].class)))
|
||||||
|
.thenReturn(getFixtureAsDocument("Logowanie-certyfikat.html"));
|
||||||
|
Mockito.doCallRealMethod().when(client).setSymbol(Mockito.anyString());
|
||||||
|
Mockito.when(client.getSymbol()).thenCallRealMethod();
|
||||||
Login login = new Login(client);
|
Login login = new Login(client);
|
||||||
|
|
||||||
Assert.assertEquals("d123", login.login("a@a", "pswd", "d123"));
|
Assert.assertEquals("d123", login.login("a@a", "pswd", "d123"));
|
||||||
@ -58,21 +62,30 @@ public class LoginTest {
|
|||||||
|
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
getFixtureAsString("cert-stock.xml").replaceAll("\\s+", ""),
|
getFixtureAsString("cert-stock.xml").replaceAll("\\s+", ""),
|
||||||
login.sendCredentials("a@a", "passwd").select("input[name=wresult]").attr("value").replaceAll("\\s+","")
|
login.sendCredentials("a@a", "passwd")
|
||||||
|
.select("input[name=wresult]")
|
||||||
|
.attr("value")
|
||||||
|
.replaceAll("\\s+", "")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sendCertificateNotDefaultSymbolSuccessTest() throws Exception {
|
public void sendCertificateNotDefaultSymbolSuccessTest() throws Exception {
|
||||||
Login login = new Login(getClient("Logowanie-success.html"));
|
Client client = getClient("Logowanie-success.html");
|
||||||
|
Mockito.doCallRealMethod().when(client).setSymbol(Mockito.anyString());
|
||||||
|
Mockito.when(client.getSymbol()).thenCallRealMethod();
|
||||||
|
Login login = new Login(client);
|
||||||
|
|
||||||
Assert.assertEquals("wulkanowyschool321",
|
Assert.assertEquals("wulkanowyschool321", login.sendCertificate(
|
||||||
login.sendCertificate(new Document(""), "wulkanowyschool321"));
|
getFixtureAsDocument("Logowanie-certyfikat.html"), "wulkanowyschool321"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sendCertificateDefaultSymbolSuccessTest() throws Exception {
|
public void sendCertificateDefaultSymbolSuccessTest() throws Exception {
|
||||||
Login login = new Login(getClient("Logowanie-success.html"));
|
Client client = getClient("Logowanie-success.html");
|
||||||
|
Mockito.doCallRealMethod().when(client).setSymbol(Mockito.anyString());
|
||||||
|
Mockito.when(client.getSymbol()).thenCallRealMethod();
|
||||||
|
Login login = new Login(client);
|
||||||
|
|
||||||
Assert.assertEquals("demo12345",
|
Assert.assertEquals("demo12345",
|
||||||
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default"));
|
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default"));
|
||||||
@ -80,16 +93,18 @@ public class LoginTest {
|
|||||||
|
|
||||||
@Test(expected = AccountPermissionException.class)
|
@Test(expected = AccountPermissionException.class)
|
||||||
public void sendCertificateAccountPermissionTest() throws Exception {
|
public void sendCertificateAccountPermissionTest() throws Exception {
|
||||||
Login login = new Login(getClient("Logowanie-brak-dostepu.html"));
|
Client client = getClient("Logowanie-brak-dostepu.html");
|
||||||
|
|
||||||
login.sendCertificate(getFixtureAsDocument("cert-stock.xml"), "demo123");
|
Login login = new Login(client);
|
||||||
|
|
||||||
|
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "demo123");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = LoginErrorException.class)
|
@Test(expected = LoginErrorException.class)
|
||||||
public void sendCertificateLoginErrorTest() throws Exception {
|
public void sendCertificateLoginErrorTest() throws Exception {
|
||||||
Login login = new Login(getClient("Logowanie-certyfikat.html")); // change to other document
|
Login login = new Login(getClient("Logowanie-certyfikat.html")); // change to other document
|
||||||
|
|
||||||
login.sendCertificate(getFixtureAsDocument("cert-stock.xml"), "demo123");
|
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "demo123");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -101,10 +116,10 @@ public class LoginTest {
|
|||||||
Assert.assertEquals("demo12345", login.findSymbolInCertificate(certificate));
|
Assert.assertEquals("demo12345", login.findSymbolInCertificate(certificate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = AccountPermissionException.class)
|
||||||
public void findSymbolInInvalidCertificateTest() throws Exception {
|
public void findSymbolInCertificateWithoutSecondInstanceTest() throws Exception {
|
||||||
Login login = new Login(getClient("Logowanie-certyfikat.html"));
|
Login login = new Login(getClient("Logowanie-certyfikat.html"));
|
||||||
|
|
||||||
Assert.assertEquals("", login.findSymbolInCertificate("<xml></xml>")); // change to real cert with empty symbols
|
login.findSymbolInCertificate(getFixtureAsString("cert-no-symbols.xml"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="MainDiv">
|
<div id="MainDiv">
|
||||||
<form>
|
<form>
|
||||||
|
<div class="LogOnBoard">
|
||||||
|
<h1 id="h1Default">Logowanie</h1>
|
||||||
|
</div>
|
||||||
<div class="ErrorMessage center">
|
<div class="ErrorMessage center">
|
||||||
Zła nazwa użytkownika lub hasło
|
Zła nazwa użytkownika lub hasło
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
|
||||||
|
<trust:RequestSecurityTokenResponse Context="https://uonetplus.fakelog.cf/Default/LoginEndpoint.aspx">
|
||||||
|
<trust:RequestedSecurityToken>
|
||||||
|
<saml:Assertion AssertionID="_12345678-1234-1234-1234-1234567890ab" IssueInstant="2017-10-18T22:00:29.006Z" Issuer="CUFSTokenService" MajorVersion="1" MinorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
|
||||||
|
<saml:AttributeStatement>
|
||||||
|
<saml:Attribute AttributeName="UserInstance" AttributeNamespace="http://schemas.fakelog.cf/ws/identity/claims">
|
||||||
|
<saml:AttributeValue>Default</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
</saml:AttributeStatement>
|
||||||
|
</saml:Assertion>
|
||||||
|
</trust:RequestedSecurityToken>
|
||||||
|
</trust:RequestSecurityTokenResponse>
|
||||||
|
</trust:RequestSecurityTokenResponseCollection>
|
@ -52,7 +52,7 @@ public class ResourcesRepository implements ResourcesContract {
|
|||||||
} else if (exception instanceof SocketTimeoutException) {
|
} else if (exception instanceof SocketTimeoutException) {
|
||||||
return resources.getString(R.string.generic_timeout_error);
|
return resources.getString(R.string.generic_timeout_error);
|
||||||
} else if (exception instanceof NotLoggedInErrorException || exception instanceof IOException) {
|
} else if (exception instanceof NotLoggedInErrorException || exception instanceof IOException) {
|
||||||
return resources.getString(R.string.login_denied_text);
|
return resources.getString(R.string.login_failed_text);
|
||||||
} else {
|
} else {
|
||||||
return exception.getMessage();
|
return exception.getMessage();
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<string name="login_accepted_text">Pomyślnie zalogowano</string>
|
<string name="login_accepted_text">Pomyślnie zalogowano</string>
|
||||||
<string name="login_bad_credentials_text">Niepoprawny e-mail lub hasło</string>
|
<string name="login_bad_credentials_text">Niepoprawny e-mail lub hasło</string>
|
||||||
<string name="login_bad_account_permission_text">Brak uprawnień do otwarcia dziennika. Sprawdź wprowadzoną nazwę powiatu</string>
|
<string name="login_bad_account_permission_text">Brak uprawnień do otwarcia dziennika. Sprawdź wprowadzoną nazwę powiatu</string>
|
||||||
<string name="login_denied_text">Logowanie nie powiodło się. Spróbuj zrestartować aplikację</string>
|
<string name="login_failed_text">Logowanie nie powiodło się. Spróbuj ponownie lub zrestartuj aplikację</string>
|
||||||
<string name="action_create_account">Nie masz jeszcze konta? Załóż je</string>
|
<string name="action_create_account">Nie masz jeszcze konta? Załóż je</string>
|
||||||
<string name="action_forgot_password">Zapomniałeś hasła?</string>
|
<string name="action_forgot_password">Zapomniałeś hasła?</string>
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<string name="login_accepted_text">Login is successful</string>
|
<string name="login_accepted_text">Login is successful</string>
|
||||||
<string name="login_bad_credentials_text">Bad e-mail or password</string>
|
<string name="login_bad_credentials_text">Bad e-mail or password</string>
|
||||||
<string name="login_bad_account_permission_text">No permission to open log. Check entered symbol</string>
|
<string name="login_bad_account_permission_text">No permission to open log. Check entered symbol</string>
|
||||||
<string name="login_denied_text">Login is failed. Try restart the app</string>
|
<string name="login_failed_text">Login is failed. Try again or restart the app</string>
|
||||||
<string name="action_create_account">No account yet? Create one</string>
|
<string name="action_create_account">No account yet? Create one</string>
|
||||||
<string name="action_forgot_password">Forgot password?</string>
|
<string name="action_forgot_password">Forgot password?</string>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user