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

[API] Improve login (#83)

This commit is contained in:
Mikołaj Pich 2018-04-20 20:30:39 +02:00 committed by Rafał Borcz
parent b7a6b71a4d
commit 2fd5b0f6ee
26 changed files with 1025 additions and 254 deletions

View File

@ -21,11 +21,9 @@ public class Client {
private String password;
private String symbol = "Default";
private String symbol;
private Login login;
private Date lastSuccessRequest = new Date();
private Date lastSuccessRequest = null;
private Cookies cookies = new Cookies();
@ -56,25 +54,16 @@ public class Client {
return;
}
this.symbol = getLogin().login(email, password, symbol);
this.cookies = new Cookies();
this.symbol = new Login(this).login(email, password, symbol);
}
private boolean isLoggedIn() {
return getCookies().size() > 0 &&
return getCookies().size() > 0 && lastSuccessRequest != null &&
29 > TimeUnit.MILLISECONDS.toMinutes(new Date().getTime() - lastSuccessRequest.getTime());
}
Login getLogin() {
if (null != login) {
return login;
}
login = new Login(this);
return login;
}
public String getSymbol() {
return symbol;
}
@ -83,6 +72,10 @@ public class Client {
this.symbol = symbol;
}
public void addCookies(Map<String, String> items) {
cookies.addItems(items);
}
private Map<String, String> getCookies() {
return cookies.getItems();
}
@ -98,8 +91,22 @@ public class Client {
.replace("{symbol}", symbol);
}
Document getPageByUrl(String url) throws IOException, VulcanException {
login();
public Document getPageByUrl(String url) throws IOException, VulcanException {
return getPageByUrl(url, true, null);
}
public Document getPageByUrl(String url, boolean loginBefore) throws IOException, VulcanException {
return getPageByUrl(url, loginBefore, null);
}
public Document getPageByUrl(String url, boolean loginBefore, Map<String, String> cookies) throws IOException, VulcanException {
if (loginBefore) {
login();
}
if (null != cookies) {
this.cookies.addItems(cookies);
}
Connection.Response response = Jsoup.connect(getFilledUrl(url))
.followRedirects(true)
@ -110,7 +117,9 @@ public class Client {
Document doc = checkForErrors(response.parse());
lastSuccessRequest = new Date();
if (loginBefore) {
lastSuccessRequest = new Date();
}
return doc;
}
@ -169,6 +178,8 @@ public class Client {
}
Document checkForErrors(Document doc) throws VulcanException {
lastSuccessRequest = null;
String title = doc.select("title").text();
if ("Przerwa techniczna".equals(title)) {
throw new VulcanOfflineException(title);
@ -179,6 +190,10 @@ public class Client {
throw new NotLoggedInErrorException(singIn);
}
if ("Błąd strony".equals(title)) {
throw new VulcanException("Nieznany błąd");
}
return doc;
}
}

View File

@ -0,0 +1,50 @@
package io.github.wulkanowy.api;
public class Diary implements ParamItem {
private String id = "";
private String studentId = "";
private String name = "";
private boolean current = false;
public String getId() {
return id;
}
public Diary setId(String id) {
this.id = id;
return this;
}
public String getStudentId() {
return studentId;
}
@Override
public Diary setStudentId(String studentId) {
this.studentId = studentId;
return this;
}
public String getName() {
return name;
}
public Diary setName(String name) {
this.name = name;
return this;
}
@Override
public boolean isCurrent() {
return current;
}
public Diary setCurrent(boolean current) {
this.current = current;
return this;
}
}

View File

@ -0,0 +1,14 @@
package io.github.wulkanowy.api;
interface ParamItem {
ParamItem setId(String id);
ParamItem setStudentId(String id);
ParamItem setName(String name);
ParamItem setCurrent(boolean isCurrent);
boolean isCurrent();
}

View File

@ -1,21 +1,14 @@
package io.github.wulkanowy.api;
public class Semester {
private String number = "";
public class Semester implements ParamItem {
private String id = "";
private boolean isCurrent = false;
private String studentId = "";
public String getNumber() {
return number;
}
private String name = "";
public Semester setNumber(String number) {
this.number = number;
return this;
}
private boolean current = false;
public String getId() {
return id;
@ -26,12 +19,31 @@ public class Semester {
return this;
}
public String getStudentId() {
return studentId;
}
@Override
public Semester setStudentId(String studentId) {
this.studentId = studentId;
return this;
}
public String getName() {
return name;
}
public Semester setName(String number) {
this.name = number;
return this;
}
public boolean isCurrent() {
return isCurrent;
return current;
}
public Semester setCurrent(boolean current) {
isCurrent = current;
this.current = current;
return this;
}
}

View File

@ -8,17 +8,25 @@ import java.util.List;
public interface SnP {
String getId();
String getSchoolID();
StudentAndParent storeContextCookies() throws IOException, VulcanException;
void setDiaryID(String id);
String getStudentID();
List<Student> getStudents() throws IOException, VulcanException;
StudentAndParent setUp() throws IOException, VulcanException;
String getRowDataChildValue(Element e, int index);
Document getSnPPageDocument(String url) throws IOException, VulcanException;
List<Diary> getDiaries() throws IOException, VulcanException;
List<Semester> getSemesters() throws IOException, VulcanException;
List<Semester> getSemesters(Document gradesPage);
Semester getCurrentSemester(List<Semester> semesterList);
<T> T getCurrent(List<? extends ParamItem> list);
}

View File

@ -0,0 +1,46 @@
package io.github.wulkanowy.api;
public class Student implements ParamItem {
private String id = "";
private String name = "";
private boolean current = false;
public String getId() {
return id;
}
public Student setId(String id) {
this.id = id;
return this;
}
public String getStudentId() {
return getId();
}
@Override
public Student setStudentId(String studentId) {
return setId(studentId);
}
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public boolean isCurrent() {
return current;
}
public Student setCurrent(boolean current) {
this.current = current;
return this;
}
}

View File

@ -5,8 +5,11 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class StudentAndParent implements SnP {
@ -18,28 +21,47 @@ public class StudentAndParent implements SnP {
private Client client;
private String id;
private String schoolID;
StudentAndParent(Client client, String id) {
private String studentID;
private String diaryID;
StudentAndParent(Client client, String schoolID, String studentID, String diaryID) {
this.client = client;
this.id = id;
this.schoolID = schoolID;
this.studentID = studentID;
this.diaryID = diaryID;
}
private String getBaseUrl() {
return BASE_URL.replace("{ID}", getId());
}
public StudentAndParent setUp() throws IOException, VulcanException {
if (null == getStudentID() || "".equals(getStudentID())) {
Document doc = client.getPageByUrl(getSnpHomePageUrl());
public String getId() {
return id;
}
Student student = getCurrent(getStudents(doc));
studentID = student.getId();
Diary diary = getCurrent(getDiaries(doc));
diaryID = diary.getId();
}
public StudentAndParent storeContextCookies() throws IOException, VulcanException {
client.getPageByUrl(getSnpHomePageUrl());
return this;
}
public String getSchoolID() {
return schoolID;
}
public String getStudentID() {
return studentID;
}
private String getBaseUrl() {
return BASE_URL.replace("{ID}", getSchoolID());
}
String getSnpHomePageUrl() throws IOException, VulcanException {
if (null != getId()) {
if (null != getSchoolID()) {
return getBaseUrl();
}
@ -53,7 +75,7 @@ public class StudentAndParent implements SnP {
String snpPageUrl = studentTileLink.attr("href");
this.id = getExtractedIdFromUrl(snpPageUrl);
this.schoolID = getExtractedIdFromUrl(snpPageUrl);
return snpPageUrl;
}
@ -72,8 +94,39 @@ public class StudentAndParent implements SnP {
return e.select(".daneWiersz .wartosc").get(index - 1).text();
}
public void setDiaryID(String id) {
this.diaryID = id;
}
public Document getSnPPageDocument(String url) throws IOException, VulcanException {
return client.getPageByUrl(getBaseUrl() + url);
Map<String, String> cookies = new HashMap<>();
cookies.put("idBiezacyDziennik", diaryID);
cookies.put("idBiezacyUczen", studentID);
client.addCookies(cookies);
Document doc = client.getPageByUrl(getBaseUrl() + url, true, cookies);
if ("Witryna ucznia i rodzica Strona główna".equals(doc.select("title").first().text())) {
throw new VulcanException("Sesja została nieprawidłowo zainicjowana");
}
return doc;
}
public List<Diary> getDiaries() throws IOException, VulcanException {
return getDiaries(client.getPageByUrl(getBaseUrl()));
}
private List<Diary> getDiaries(Document doc) throws IOException, VulcanException {
return getList(doc.select("#dziennikDropDownList option"), Diary.class);
}
public List<Student> getStudents() throws IOException, VulcanException {
return getStudents(client.getPageByUrl(getBaseUrl()));
}
private List<Student> getStudents(Document doc) throws IOException, VulcanException {
return getList(doc.select("#uczenDropDownList option"), Student.class);
}
public List<Semester> getSemesters() throws IOException, VulcanException {
@ -88,9 +141,9 @@ public class StudentAndParent implements SnP {
for (Element e : semesterOptions) {
Semester semester = new Semester()
.setId(e.text())
.setNumber(e.attr("value"));
.setName(e.attr("value"));
if ("selected".equals(e.attr("selected"))) {
if (isCurrent(e)) {
semester.setCurrent(true);
}
@ -100,15 +153,47 @@ public class StudentAndParent implements SnP {
return semesters;
}
public Semester getCurrentSemester(List<Semester> semesterList) {
Semester current = null;
for (Semester s : semesterList) {
@SuppressWarnings("unchecked")
private <T> List<T> getList(Elements options, Class<? extends ParamItem> type) throws IOException, VulcanException {
List<T> list = new ArrayList<>();
for (Element e : options) {
URL url = new URL(e.val());
try {
ParamItem item = type.newInstance()
.setId(url.getQuery().split("=")[1])
.setName(e.text());
if (isCurrent(e)) {
item.setCurrent(true);
}
if (item instanceof Diary) {
item.setStudentId(getStudentID());
}
list.add((T) item);
} catch (Exception ex) {
throw new VulcanException("Error while trying to parse params list", ex);
}
}
return list;
}
@SuppressWarnings("unchecked")
public <T> T getCurrent(List<? extends ParamItem> list) {
ParamItem current = null;
for (ParamItem s : list) {
if (s.isCurrent()) {
current = s;
break;
}
}
return current;
return (T) current;
}
private boolean isCurrent(Element e) {
return "selected".equals(e.attr("selected"));
}
}

View File

@ -18,16 +18,22 @@ import io.github.wulkanowy.api.user.FamilyInformation;
public class Vulcan {
private String id;
private SnP snp;
private Client client;
public void setCredentials(String email, String password, String symbol, String id) {
client = new Client(email, password, symbol);
private String schoolId;
this.id = id;
private String studentId;
private String diaryId;
public void setCredentials(String email, String password, String symbol, String schoolId, String studentId, String diaryId) {
this.schoolId = schoolId;
this.studentId = studentId;
this.diaryId = diaryId;
client = new Client(email, password, symbol);
}
public Client getClient() throws NotLoggedInErrorException {
@ -43,20 +49,17 @@ public class Vulcan {
}
public SnP getStudentAndParent() throws IOException, VulcanException {
public SnP getStudentAndParent() throws VulcanException, IOException {
if (null != this.snp) {
return this.snp;
}
this.snp = new StudentAndParent(getClient(), id).storeContextCookies();
this.snp = new StudentAndParent(getClient(), schoolId, studentId, diaryId)
.setUp();
return this.snp;
}
public String getId() throws IOException, VulcanException {
return getStudentAndParent().getId();
}
public AttendanceTable getAttendanceTable() throws IOException, VulcanException {
return new AttendanceTable(getStudentAndParent());
}

View File

@ -1,8 +1,12 @@
package io.github.wulkanowy.api;
public abstract class VulcanException extends Exception {
public class VulcanException extends Exception {
protected VulcanException(String message) {
super(message);
}
protected VulcanException(String message, Exception e) {
super(message, e);
}
}

View File

@ -22,7 +22,7 @@ public class GradesList {
private static final String GRADES_PAGE_URL = "Oceny/Wszystkie?details=2&okres=";
private SnP snp = null;
private SnP snp;
private List<Grade> grades = new ArrayList<>();
@ -41,43 +41,61 @@ public class GradesList {
public List<Grade> getAll(String semester) throws IOException, ParseException, VulcanException {
Document gradesPage = snp.getSnPPageDocument(getGradesPageUrl() + semester);
Elements gradesRows = gradesPage.select(".ocenySzczegoly-table > tbody > tr");
Semester currentSemester = snp.getCurrentSemester(snp.getSemesters(gradesPage));
if ("".equals(semester)) {
List<Semester> semesterList = snp.getSemesters(gradesPage);
Semester currentSemester = snp.getCurrent(semesterList);
semester = currentSemester.getName();
}
for (Element row : gradesRows) {
if ("Brak ocen".equals(row.select("td:nth-child(2)").text())) {
continue;
}
String descriptions = row.select("td:nth-child(3)").text();
String symbol = descriptions.split(", ")[0];
String description = descriptions.replaceFirst(symbol, "").replaceFirst(", ", "");
Pattern pattern = Pattern.compile("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})");
Matcher matcher = pattern.matcher(row.select("td:nth-child(2) span.ocenaCzastkowa")
.attr("style"));
String color = "";
while (matcher.find()) {
color = matcher.group(1);
}
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT);
Date d = sdf.parse(row.select("td:nth-child(5)").text());
sdf.applyPattern("yyyy-MM-dd");
grades.add(new Grade()
.setSubject(row.select("td:nth-child(1)").text())
.setValue(row.select("td:nth-child(2)").text())
.setColor(color)
.setSymbol(symbol)
.setDescription(description)
.setWeight(row.select("td:nth-child(4)").text())
.setDate(sdf.format(d))
.setTeacher(row.select("td:nth-child(6)").text())
.setSemester(currentSemester.getNumber())
);
grades.add(getGrade(row, semester));
}
return grades;
}
private Grade getGrade(Element row, String semester) throws ParseException {
String descriptions = row.select("td:nth-child(3)").text();
String symbol = descriptions.split(", ")[0];
String description = descriptions.replaceFirst(symbol, "").replaceFirst(", ", "");
String color = getColor(row.select("td:nth-child(2) span.ocenaCzastkowa").attr("style"));
String date = formatDate(row.select("td:nth-child(5)").text());
return new Grade()
.setSubject(row.select("td:nth-child(1)").text())
.setValue(row.select("td:nth-child(2)").text())
.setColor(color)
.setSymbol(symbol)
.setDescription(description)
.setWeight(row.select("td:nth-child(4)").text())
.setDate(date)
.setTeacher(row.select("td:nth-child(6)").text())
.setSemester(semester);
}
private String getColor(String styleAttr) {
Pattern pattern = Pattern.compile("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})");
Matcher matcher = pattern.matcher(styleAttr);
String color = "";
while (matcher.find()) {
color = matcher.group(1);
}
return color;
}
private String formatDate(String date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT);
Date d = sdf.parse(date);
sdf.applyPattern("yyyy-MM-dd");
return sdf.format(d);
}
}

View File

@ -18,26 +18,19 @@ public class Login {
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx%26wctx%3D" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx";
private static final String LOGIN_ENDPOINT_PAGE_URL =
"{schema}://uonetplus.{host}/{symbol}/LoginEndpoint.aspx";
private Client client;
private String symbol;
public Login(Client client) {
this.client = client;
}
public String login(String email, String password, String symbol) throws VulcanException, IOException {
String certificate = sendCredentials(email, password, symbol);
Document certDoc = sendCredentials(email, password);
return sendCertificate(certificate, symbol);
return sendCertificate(certDoc, symbol);
}
String sendCredentials(String email, String password, String symbol) throws IOException, VulcanException {
this.symbol = symbol;
Document sendCredentials(String email, String password) throws IOException, VulcanException {
Document html = client.postPageByUrl(LOGIN_PAGE_URL, new String[][]{
{"LoginName", email},
{"Password", password}
@ -48,27 +41,37 @@ public class Login {
throw new BadCredentialsException(errorMessage.text());
}
return html.select("input[name=wresult]").attr("value");
return html;
}
String sendCertificate(String certificate, String defaultSymbol) throws IOException, VulcanException {
this.symbol = findSymbol(defaultSymbol, certificate);
client.setSymbol(this.symbol);
String sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException {
String certificate = doc.select("input[name=wresult]").val();
String title = client.postPageByUrl(LOGIN_ENDPOINT_PAGE_URL, new String[][]{
{"wa", "wsignin1.0"},
{"wresult", certificate}
}).select("title").text();
String symbol = findSymbol(defaultSymbol, certificate);
client.setSymbol(symbol);
Document targetDoc = sendCertData(doc);
String title = targetDoc.select("title").text();
if ("Logowanie".equals(title)) {
throw new AccountPermissionException("No account access. Try another symbol");
}
if (!"Uonet+".equals(title)) {
throw new LoginErrorException("Could not log in, unknown error");
throw new LoginErrorException("Expected page title `UONET+`, got " + title);
}
return this.symbol;
return symbol;
}
private Document sendCertData(Document doc) throws IOException, VulcanException {
String url = doc.select("form[name=hiddenform]").attr("action");
return client.postPageByUrl(url.replaceFirst("Default", "{symbol}"), new String[][]{
{"wa", "wsignin1.0"},
{"wresult", doc.select("input[name=wresult]").val()},
{"wctx", doc.select("input[name=wctx]").val()}
});
}
private String findSymbol(String symbol, String certificate) {
@ -80,14 +83,14 @@ public class Login {
}
String findSymbolInCertificate(String certificate) {
Elements els = Jsoup
Elements instances = Jsoup
.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
.select("[AttributeName=\"UserInstance\"] samlAttributeValue");
if (els.isEmpty()) {
if (instances.isEmpty()) {
return "";
}
return els.get(1).text();
return instances.get(1).text();
}
}

View File

@ -1,13 +1,10 @@
package io.github.wulkanowy.api;
import org.hamcrest.CoreMatchers;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.Assert;
import org.junit.Test;
import io.github.wulkanowy.api.login.Login;
public class ClientTest {
private String getFixtureAsString(String fixtureFileName) {
@ -49,20 +46,6 @@ public class ClientTest {
client.checkForErrors(doc);
}
@Test
public void getClientTest() throws Exception {
Client client = new Client("", "", "");
Assert.assertThat(client.getLogin(), CoreMatchers.instanceOf(Login.class));
}
@Test
public void getClientTwiceTest() throws Exception {
Client client = new Client("", "", "");
Assert.assertEquals(client.getLogin(), client.getLogin());
}
@Test
public void getFilledUrlTest() throws Exception {
Client client = new Client("http://fakelog.cf\\\\admin", "", "symbol123");

View File

@ -7,6 +7,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -22,18 +23,21 @@ public class StudentAndParentTest {
client = Mockito.mock(Client.class);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(gradesPageDocument);
Mockito.when(client.getPageByUrl(
Mockito.anyString(),
Mockito.anyBoolean(), Mockito.anyMap())).thenReturn(gradesPageDocument);
}
@Test
public void snpTest() throws Exception {
StudentAndParent snp = new StudentAndParent(client, "id123");
Assert.assertEquals("id123", snp.getId());
public void snpTest() {
StudentAndParent snp = new StudentAndParent(client, "id123", null, null);
Assert.assertEquals("id123", snp.getSchoolID());
}
@Test
public void getSnpPageUrlWithIdTest() throws Exception {
Assert.assertEquals("{schema}://uonetplus-opiekun.{host}/{symbol}/123456/",
(new StudentAndParent(client, "123456")).getSnpHomePageUrl());
(new StudentAndParent(client, "123456", null, null)).getSnpHomePageUrl());
}
@Test
@ -43,7 +47,7 @@ public class StudentAndParentTest {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(startPageDocument);
StudentAndParent snp = new StudentAndParent(client, null);
StudentAndParent snp = new StudentAndParent(client, null, null, null);
Assert.assertEquals("https://uonetplus-opiekun.vulcan.net.pl/symbol/534213/Start/Index/",
snp.getSnpHomePageUrl());
@ -56,7 +60,7 @@ public class StudentAndParentTest {
);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(wrongPageDocument);
StudentAndParent snp = new StudentAndParent(client, null);
StudentAndParent snp = new StudentAndParent(client, null, null, null);
snp.getSnpHomePageUrl();
}
@ -64,7 +68,7 @@ public class StudentAndParentTest {
@Test
public void getExtractedIDStandardTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
Assert.assertEquals("123456", snp.getExtractedIdFromUrl("https://uonetplus-opiekun"
+ ".vulcan.net.pl/powiat/123456/Start/Index/"));
}
@ -72,7 +76,7 @@ public class StudentAndParentTest {
@Test
public void getExtractedIDDemoTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
Assert.assertEquals("demo12345",
snp.getExtractedIdFromUrl("https://uonetplus-opiekun.vulcan.net.pl/demoupowiat/demo12345/Start/Index/"));
}
@ -80,44 +84,75 @@ public class StudentAndParentTest {
@Test(expected = NotLoggedInErrorException.class)
public void getExtractedIDNotLoggedTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
Assert.assertEquals("123",
snp.getExtractedIdFromUrl("https://uonetplus.vulcan.net.pl/powiat/"));
}
@Test
public void getSemestersTest() throws Exception {
SnP snp = new StudentAndParent(client, "123456");
SnP snp = new StudentAndParent(client, "123456", null, null);
List<Semester> semesters = snp.getSemesters();
Assert.assertEquals(2, semesters.size());
Assert.assertEquals("1", semesters.get(0).getId());
Assert.assertEquals("1234", semesters.get(0).getNumber());
Assert.assertEquals("1234", semesters.get(0).getName());
Assert.assertFalse(semesters.get(0).isCurrent());
Assert.assertEquals("2", semesters.get(1).getId());
Assert.assertEquals("1235", semesters.get(1).getNumber());
Assert.assertEquals("1235", semesters.get(1).getName());
Assert.assertTrue(semesters.get(1).isCurrent());
}
@Test
public void getCurrentSemesterTest() throws Exception {
public void getCurrentSemesterTest() {
List<Semester> semesters = new ArrayList<>();
semesters.add(new Semester().setNumber("1500100900").setId("1").setCurrent(false));
semesters.add(new Semester().setNumber("1500100901").setId("2").setCurrent(true));
semesters.add(new Semester().setName("1500100900").setId("1").setCurrent(false));
semesters.add(new Semester().setName("1500100901").setId("2").setCurrent(true));
SnP snp = new StudentAndParent(client, "");
Assert.assertTrue(snp.getCurrentSemester(semesters).isCurrent());
Assert.assertEquals("2", snp.getCurrentSemester(semesters).getId());
Assert.assertEquals("1500100901", snp.getCurrentSemester(semesters).getNumber());
SnP snp = new StudentAndParent(client, "", null, null);
Semester semester = snp.getCurrent(semesters);
Assert.assertTrue(semester.isCurrent());
Assert.assertEquals("2", semester.getId());
Assert.assertEquals("1500100901", semester.getName());
}
@Test
public void getCurrentSemesterFromEmptyTest() throws Exception {
SnP snp = new StudentAndParent(client, "");
public void getCurrentSemesterFromEmptyTest() {
SnP snp = new StudentAndParent(client, "", null, null);
List<Semester> semesters = new ArrayList<>();
Assert.assertNull(snp.getCurrentSemester(semesters));
Assert.assertNull(snp.getCurrent(semesters));
}
@Test
public void getDiariesAndStudentTest() throws IOException, VulcanException {
Document snpHome = Jsoup.parse(FixtureHelper.getAsString(
getClass().getResourceAsStream("StudentAndParent.html")));
client = Mockito.mock(Client.class);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(snpHome);
SnP snp = new StudentAndParent(client, "", null, null);
snp.setUp();
Assert.assertEquals("3Ti 2017", snp.getDiaries().get(0).getName());
Assert.assertEquals("2Ti 2016", snp.getDiaries().get(1).getName());
Assert.assertEquals("1Ti 2015", snp.getDiaries().get(2).getName());
Assert.assertEquals("1300", snp.getDiaries().get(0).getId());
Assert.assertEquals("1200", snp.getDiaries().get(1).getId());
Assert.assertEquals("1100", snp.getDiaries().get(2).getId());
Assert.assertTrue(snp.getDiaries().get(0).isCurrent());
Assert.assertFalse(snp.getDiaries().get(1).isCurrent());
Assert.assertFalse(snp.getDiaries().get(2).isCurrent());
Assert.assertEquals("100", snp.getDiaries().get(0).getStudentId());
Assert.assertEquals("Jan Kowal", snp.getStudents().get(0).getName());
Assert.assertEquals("100", snp.getStudents().get(0).getStudentId());
}
}

View File

@ -16,7 +16,7 @@ public abstract class StudentAndParentTestCase {
Mockito.when(snp.getSnPPageDocument(Mockito.anyString()))
.thenReturn(tablePageDocument);
Mockito.when(snp.getSemesters(Mockito.any(Document.class))).thenCallRealMethod();
Mockito.when(snp.getCurrentSemester(Mockito.<Semester>anyList()))
Mockito.when(snp.getCurrent(Mockito.<Semester>anyList()))
.thenCallRealMethod();
Mockito.when(snp.getRowDataChildValue(Mockito.any(Element.class),
Mockito.anyInt())).thenCallRealMethod();

View File

@ -16,7 +16,7 @@ public class VulcanTest {
@Test
public void getClientTest() throws Exception {
Vulcan vulcan = new Vulcan();
vulcan.setCredentials("email", "password", "symbol", null);
vulcan.setCredentials("email", "password", "symbol", null, null, null);
Assert.assertThat(vulcan.getClient(), CoreMatchers.instanceOf(Client.class));
}
@ -24,7 +24,7 @@ public class VulcanTest {
@Test
public void getClientTwiceTest() throws Exception {
Vulcan vulcan = new Vulcan();
vulcan.setCredentials("email", "password", "symbol", null);
vulcan.setCredentials("email", "password", "symbol", null, null, null);
Assert.assertEquals(vulcan.getClient(), vulcan.getClient());
}

View File

@ -11,12 +11,16 @@ import io.github.wulkanowy.api.FixtureHelper;
public class LoginTest {
private Document getFixtureAsDocument(String fixtureFileName) {
return Jsoup.parse(getFixtureAsString(fixtureFileName));
}
private String getFixtureAsString(String fixtureFileName) {
return FixtureHelper.getAsString(getClass().getResourceAsStream(fixtureFileName));
}
private Client getClient(String fixtureFileName) throws Exception {
Document doc = Jsoup.parse(getFixtureAsString(fixtureFileName));
Document doc = getFixtureAsDocument(fixtureFileName);
Client client = Mockito.mock(Client.class);
Mockito.when(client.postPageByUrl(Mockito.anyString(), Mockito.any(String[][].class))).thenReturn(doc);
@ -26,25 +30,36 @@ public class LoginTest {
@Test
public void loginTest() throws Exception {
Login login = new Login(getClient("Logowanie-success.html"));
Client client = getClient("Logowanie-success.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.thenReturn(getFixtureAsDocument("Logowanie-error.html"));
Login login = new Login(client);
Assert.assertEquals("d123", login.login("a@a", "pswd", "d123"));
}
@Test(expected = BadCredentialsException.class)
public void sendWrongCredentialsTest() throws Exception {
Login login = new Login(getClient("Logowanie-error.html"));
Client client = getClient("Logowanie-error.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.thenReturn(getFixtureAsDocument("Logowanie-error.html")); // -error.html because it html with form used by
Login login = new Login(client);
login.sendCredentials("a@a", "pswd", "d123");
login.sendCredentials("a@a", "pswd");
}
@Test
public void sendCredentialsCertificateTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html"));
Client client = getClient("Logowanie-certyfikat.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.thenReturn(getFixtureAsDocument("Logowanie-error.html")); // -error.html because it html with form used by
Login login = new Login(client);
Assert.assertEquals(
getFixtureAsString("cert.xml").replaceAll("\\s+",""),
login.sendCredentials("a@a", "passwd", "d123").replaceAll("\\s+","")
login.sendCredentials("a@a", "passwd")
.select("input[name=wresult]").attr("value")
.replaceAll("\\s+","")
);
}
@ -53,7 +68,7 @@ public class LoginTest {
Login login = new Login(getClient("Logowanie-success.html"));
Assert.assertEquals("wulkanowyschool321",
login.sendCertificate("", "wulkanowyschool321"));
login.sendCertificate(new Document(""), "wulkanowyschool321"));
}
@Test
@ -61,21 +76,21 @@ public class LoginTest {
Login login = new Login(getClient("Logowanie-success.html"));
Assert.assertEquals("demo12345",
login.sendCertificate(getFixtureAsString("cert.xml"), "Default"));
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default"));
}
@Test(expected = AccountPermissionException.class)
public void sendCertificateAccountPermissionTest() throws Exception {
Login login = new Login(getClient("Logowanie-brak-dostepu.html"));
login.sendCertificate(getFixtureAsString("cert.xml"), "demo123");
login.sendCertificate(getFixtureAsDocument("cert.xml"), "demo123");
}
@Test(expected = LoginErrorException.class)
public void sendCertificateLoginErrorTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html")); // change to other document
login.sendCertificate(getFixtureAsString("cert.xml"), "demo123");
login.sendCertificate(getFixtureAsDocument("cert.xml"), "demo123");
}
@Test

View File

@ -15,7 +15,8 @@
<option selected="selected" value="1235">2</option>
</select>
</div>
</main>
</div>
</main>
<footer>wersja: 17.05.0000.24042</footer>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica Strona gł&#243;wna</title>
</head>
<body>
<ul id="idSection">
<li>
<label for="uczenDropDownList">Uczeń:</label>
<select id="uczenDropDownList" name="uczenDropDownList">
<option selected="selected"
value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Uczen/UczenOnChange?&amp;id=100">
Jan Kowal
</option>
</select>
</li>
<li>
<label for="dziennikDropDownList">Dziennik:</label>
<select id="dziennikDropDownList" name="dziennikDropDownList">
<option selected="selected"
value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&amp;id=1300">
3Ti 2017
</option>
<option value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&amp;id=1200">
2Ti 2016
</option>
<option value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&amp;id=1100">
1Ti 2015
</option>
</select>
</li>
</ul>
<footer>wersja: 17.09.0008.26553</footer>
</body>
</html>

View File

@ -62,7 +62,7 @@ android {
}
greendao {
schemaVersion 22
schemaVersion 23
generateTests = true
}
@ -79,7 +79,6 @@ dependencies {
implementation "eu.davidea:flexible-adapter:$flexibleAdapter"
implementation "eu.davidea:flexible-adapter-ui:$flexibleUi"
implementation "org.greenrobot:greendao:$greenDao"
implementation "com.github.yuweiguocn:GreenDaoUpgradeHelper:$greenDaoHelper"
implementation "com.jakewharton:butterknife:$butterknife"
implementation "com.google.dagger:dagger-android-support:$dagger2"
implementation "com.aurelhubert:ahbottomnavigation:$ahbottom"

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
import io.github.wulkanowy.data.db.dao.entities.Diary;
import io.github.wulkanowy.data.db.dao.entities.DiaryDao;
public class DiaryTest extends AbstractDaoTestLongPk<DiaryDao, Diary> {
public DiaryTest() {
super(DiaryDao.class);
}
@Override
protected Diary createEntity(Long key) {
Diary entity = new Diary();
entity.setId(key);
entity.setIsCurrent(false);
return entity;
}
}

View File

@ -3,19 +3,21 @@ package io.github.wulkanowy.data.db.dao;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.github.yuweiguocn.library.greendao.MigrationHelper;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.StandardDatabase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.BuildConfig;
import io.github.wulkanowy.data.db.dao.entities.AccountDao;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.entities.DaoMaster;
import io.github.wulkanowy.data.db.dao.entities.GradeDao;
import io.github.wulkanowy.data.db.dao.entities.SubjectDao;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.migrations.Migration23;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.di.annotations.DatabaseInfo;
@ -24,29 +26,16 @@ import io.github.wulkanowy.utils.LogUtils;
@Singleton
public class DbHelper extends DaoMaster.OpenHelper {
private SharedPrefContract sharedPref;
private final SharedPrefContract sharedPref;
private final Vulcan vulcan;
@Inject
DbHelper(@ApplicationContext Context context, @DatabaseInfo String dbName,
SharedPrefContract sharedPref) {
SharedPrefContract sharedPref, Vulcan vulcan) {
super(context, dbName);
this.sharedPref = sharedPref;
}
@Override
@SuppressWarnings("unchecked")
public void onUpgrade(Database db, int oldVersion, int newVersion) {
MigrationHelper.DEBUG = BuildConfig.DEBUG;
MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {
@Override
public void onCreateAllTables(Database db, boolean ifNotExists) {
DaoMaster.createAllTables(db, ifNotExists);
}
@Override
public void onDropAllTables(Database db, boolean ifExists) {
DaoMaster.dropAllTables(db, ifExists);
}
}, AccountDao.class, SubjectDao.class, GradeDao.class);
this.vulcan = vulcan;
}
@Override
@ -55,7 +44,49 @@ public class DbHelper extends DaoMaster.OpenHelper {
DaoMaster.dropAllTables(database, true);
onCreate(database);
sharedPref.setCurrentUserId(0);
LogUtils.info("Cleaning user data oldVersion=" + oldVersion + " newVersion=" + newVersion);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
List<Migration> migrations = getMigrations();
// Only run migrations past the old version
for (Migration migration : migrations) {
if (oldVersion < migration.getVersion()) {
try {
LogUtils.info("Applying migration to db schema v" + migration.getVersion() + "...");
migration.runMigration(db, sharedPref, vulcan);
LogUtils.info("Migration " + migration.getVersion() + " complete");
} catch (Exception e) {
e.printStackTrace();
DaoMaster.dropAllTables(db, true);
sharedPref.setCurrentUserId(0);
break;
}
}
}
}
private List<Migration> getMigrations() {
List<Migration> migrations = new ArrayList<>();
migrations.add(new Migration23());
// Sorting just to be safe, in case other people add migrations in the wrong order.
Comparator<Migration> migrationComparator = new Comparator<Migration>() {
@Override
public int compare(Migration m1, Migration m2) {
return m1.getVersion().compareTo(m2.getVersion());
}
};
Collections.sort(migrations, migrationComparator);
return migrations;
}
public interface Migration {
Integer getVersion();
void runMigration(Database db, SharedPrefContract sharedPref, Vulcan vulcan) throws Exception;
}
}

View File

@ -4,6 +4,8 @@ import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Index;
import org.greenrobot.greendao.annotation.JoinProperty;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
@ -18,20 +20,29 @@ public class Account {
@Id(autoincrement = true)
private Long id;
@Index(unique = true)
@Property(nameInDb = "REAL_ID")
private String realId;
@Property(nameInDb = "SYMBOL")
private String symbol;
@Property(nameInDb = "SCHOOL_ID")
private String schoolId;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "E-MAIL")
@Property(nameInDb = "E_MAIL")
private String email;
@Property(nameInDb = "PASSWORD")
private String password;
@Property(nameInDb = "SYMBOL")
private String symbol;
@Property(nameInDb = "SNPID")
private String snpId;
@ToMany(joinProperties = {
@JoinProperty(name = "realId", referencedName = "studentId")
})
private List<Diary> diaryList;
@ToMany(referencedJoinProperty = "userId")
private List<Subject> subjectList;
@ -54,15 +65,16 @@ public class Account {
@Generated(hash = 335469827)
private transient AccountDao myDao;
@Generated(hash = 735765217)
public Account(Long id, String name, String email, String password, String symbol,
String snpId) {
@Generated(hash = 727721142)
public Account(Long id, String realId, String symbol, String schoolId, String name,
String email, String password) {
this.id = id;
this.realId = realId;
this.symbol = symbol;
this.schoolId = schoolId;
this.name = name;
this.email = email;
this.password = password;
this.symbol = symbol;
this.snpId = snpId;
}
@Generated(hash = 882125521)
@ -78,6 +90,15 @@ public class Account {
return this;
}
public String getRealId() {
return realId;
}
public Account setRealId(String realId) {
this.realId = realId;
return this;
}
public String getName() {
return name;
}
@ -114,15 +135,83 @@ public class Account {
return this;
}
public String getSnpId() {
return this.snpId;
public String getSchoolId() {
return schoolId;
}
public Account setSnpId(String snpId) {
this.snpId = snpId;
public Account setSchoolId(String schoolId) {
this.schoolId = schoolId;
return this;
}
public Account setDiaryList(List<Diary> diaryList) {
this.diaryList = diaryList;
return this;
}
public Account setSubjectList(List<Subject> subjectList) {
this.subjectList = subjectList;
return this;
}
public Account setGradeList(List<Grade> gradeList) {
this.gradeList = gradeList;
return this;
}
public Account setDayList(List<Day> dayList) {
this.dayList = dayList;
return this;
}
public DaoSession getDaoSession() {
return daoSession;
}
public Account setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
return this;
}
public AccountDao getMyDao() {
return myDao;
}
public Account setMyDao(AccountDao myDao) {
this.myDao = myDao;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1472214466)
public List<Diary> getDiaryList() {
if (diaryList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
DiaryDao targetDao = daoSession.getDiaryDao();
List<Diary> diaryListNew = targetDao._queryAccount_DiaryList(realId);
synchronized (this) {
if (diaryList == null) {
diaryList = diaryListNew;
}
}
}
return diaryList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1078514341)
public synchronized void resetDiaryList() {
diaryList = null;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
@ -183,6 +272,36 @@ public class Account {
gradeList = null;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 300459794)
public List<Day> getDayList() {
if (dayList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
DayDao targetDao = daoSession.getDayDao();
List<Day> dayListNew = targetDao._queryAccount_DayList(id);
synchronized (this) {
if (dayList == null) {
dayList = dayListNew;
}
}
}
return dayList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1010399236)
public synchronized void resetDayList() {
dayList = null;
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context.
@ -219,36 +338,6 @@ public class Account {
myDao.update(this);
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 300459794)
public List<Day> getDayList() {
if (dayList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
DayDao targetDao = daoSession.getDayDao();
List<Day> dayListNew = targetDao._queryAccount_DayList(id);
synchronized (this) {
if (dayList == null) {
dayList = dayListNew;
}
}
}
return dayList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1010399236)
public synchronized void resetDayList() {
dayList = null;
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1812283172)
public void __setDaoSession(DaoSession daoSession) {

View File

@ -0,0 +1,161 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
@Entity(
nameInDb = "Diaries",
active = true
)
public class Diary {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "STUDENT_ID")
private String studentId;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "VALUE")
private String value;
@Property(nameInDb = "IS_CURRENT")
private boolean isCurrent;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 21166549)
private transient DiaryDao myDao;
@Generated(hash = 459332202)
public Diary(Long id, String studentId, String name, String value,
boolean isCurrent) {
this.id = id;
this.studentId = studentId;
this.name = name;
this.value = value;
this.isCurrent = isCurrent;
}
@Generated(hash = 112123061)
public Diary() {
}
public Long getId() {
return id;
}
public Diary setId(Long id) {
this.id = id;
return this;
}
public String getStudentId() {
return studentId;
}
public Diary setStudentId(String studentId) {
this.studentId = studentId;
return this;
}
public String getName() {
return name;
}
public Diary setName(String name) {
this.name = name;
return this;
}
public String getValue() {
return value;
}
public Diary setValue(String value) {
this.value = value;
return this;
}
public boolean getIsCurrent() {
return isCurrent;
}
public Diary setIsCurrent(boolean current) {
isCurrent = current;
return this;
}
public DaoSession getDaoSession() {
return daoSession;
}
public Diary setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
return this;
}
public DiaryDao getMyDao() {
return myDao;
}
public Diary setMyDao(DiaryDao myDao) {
this.myDao = myDao;
return this;
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 128553479)
public void delete() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.delete(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 1942392019)
public void refresh() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.refresh(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 713229351)
public void update() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.update(this);
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 629297785)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getDiaryDao() : null;
}
}

View File

@ -0,0 +1,114 @@
package io.github.wulkanowy.data.db.dao.migrations;
import android.database.Cursor;
import android.os.AsyncTask;
import org.greenrobot.greendao.database.Database;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.github.wulkanowy.api.Diary;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.DbHelper;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.utils.security.Scrambler;
public class Migration23 implements DbHelper.Migration {
@Override
public Integer getVersion() {
return 23;
}
@Override
public void runMigration(final Database db, final SharedPrefContract sharedPref, final Vulcan vulcan) throws Exception {
createDiaryTable(db);
migrateAccountsTable(db);
final Map<String, String> user = getAccountData(db);
vulcan.setCredentials(
user.get("email"),
Scrambler.decrypt(user.get("email"), user.get("password")),
user.get("symbol"),
user.get("school_id"),
"", // inserted in code bellow
""
);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
insertDiaries(db, vulcan.getStudentAndParent().getDiaries());
updateAccount(db, vulcan.getStudentAndParent().getStudentID());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void createDiaryTable(Database db) {
db.execSQL("DROP TABLE IF EXISTS Diaries");
db.execSQL("CREATE TABLE IF NOT EXISTS \"Diaries\" (" + //
"\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
"\"STUDENT_ID\" TEXT," + // 1: studentId
"\"NAME\" TEXT," + // 2: name
"\"VALUE\" TEXT," + // 3: value
"\"IS_CURRENT\" INTEGER NOT NULL );"); // 4: isCurrent
}
private void migrateAccountsTable(Database db) {
db.execSQL("DROP TABLE IF EXISTS tmp_account");
db.execSQL("ALTER TABLE Accounts RENAME TO tmp_account");
db.execSQL("CREATE TABLE IF NOT EXISTS \"Accounts\" (" + //
"\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
"\"REAL_ID\" TEXT," + // 1: realId
"\"SYMBOL\" TEXT," + // 2: symbol
"\"SCHOOL_ID\" TEXT," + // 3: schoolId
"\"NAME\" TEXT," + // 4: name
"\"E_MAIL\" TEXT," + // 5: email
"\"PASSWORD\" TEXT);"); // 6: password
// Add Indexes
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS IDX_Accounts_REAL_ID ON \"Accounts\" (\"REAL_ID\" ASC);");
db.execSQL("INSERT INTO Accounts(NAME, E_MAIL, PASSWORD, SYMBOL, SCHOOL_ID)" +
"SELECT `NAME`, `E-MAIL`, `PASSWORD`, `SYMBOL`, `SNPID` FROM tmp_account");
db.execSQL("DROP TABLE tmp_account");
}
private Map<String, String> getAccountData(Database db) {
Map<String, String> values = new HashMap<>();
Cursor cursor = db.rawQuery("SELECT SYMBOL, SCHOOL_ID, NAME, E_MAIL, PASSWORD FROM Accounts", null);
if (cursor.moveToFirst()) {
do {
values.put("symbol", cursor.getString(cursor.getColumnIndex("SYMBOL")));
values.put("school_id", cursor.getString(cursor.getColumnIndex("SCHOOL_ID")));
values.put("name", cursor.getString(cursor.getColumnIndex("NAME")));
values.put("email", cursor.getString(cursor.getColumnIndex("E_MAIL")));
values.put("password", cursor.getString(cursor.getColumnIndex("PASSWORD")));
} while (cursor.moveToNext());
}
cursor.close();
return values;
}
private void insertDiaries(Database db, List<Diary> list) {
for (Diary diary : list) {
db.execSQL("INSERT INTO Diaries(STUDENT_ID, NAME, VALUE, IS_CURRENT) VALUES(" +
"\"" + diary.getStudentId() + "\"," +
"\"" + diary.getName() + "\"," +
"\"" + diary.getId() + "\"," +
"\"" + (diary.isCurrent() ? "1" : "0") + "\"" +
")");
}
}
private void updateAccount(Database db, String realId) {
db.execSQL("UPDATE Accounts SET REAL_ID = ?", new String[]{realId});
}
}

View File

@ -3,6 +3,9 @@ package io.github.wulkanowy.data.sync.account;
import android.content.Context;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -11,8 +14,11 @@ import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.data.db.dao.entities.Account;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Diary;
import io.github.wulkanowy.data.db.dao.entities.DiaryDao;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.utils.DataObjectConverter;
import io.github.wulkanowy.utils.LogUtils;
import io.github.wulkanowy.utils.security.CryptoException;
import io.github.wulkanowy.utils.security.Scrambler;
@ -43,22 +49,27 @@ public class AccountSync implements AccountSyncContract {
LogUtils.debug("Register new user email=" + email);
vulcan.setCredentials(email, password, symbol, null);
vulcan.setCredentials(email, password, symbol, null, null, null);
Account account = new Account()
.setName(vulcan.getBasicInformation().getPersonalData().getFirstAndLastName())
.setEmail(email)
.setPassword(Scrambler.encrypt(email, password, context))
.setSymbol(vulcan.getSymbol())
.setSnpId(vulcan.getStudentAndParent().getId());
.setSchoolId(vulcan.getStudentAndParent().getSchoolID())
.setRealId(vulcan.getStudentAndParent().getStudentID());
List<Diary> diaryList = DataObjectConverter.diariesToDiaryEntities(
vulcan.getStudentAndParent().getDiaries());
daoSession.getAccountDao().insert(account);
daoSession.getDiaryDao().insertInTx(diaryList);
sharedPref.setCurrentUserId(account.getId());
}
@Override
public void initLastUser() throws VulcanException, IOException, CryptoException {
public void initLastUser() throws IOException, CryptoException {
long userId = sharedPref.getCurrentUserId();
@ -73,6 +84,10 @@ public class AccountSync implements AccountSyncContract {
vulcan.setCredentials(account.getEmail(),
Scrambler.decrypt(account.getEmail(), account.getPassword()),
account.getSymbol(),
account.getSnpId());
account.getSchoolId(),
account.getRealId(),
daoSession.getDiaryDao().queryBuilder()
.where(DiaryDao.Properties.IsCurrent.eq(true)).unique().getValue()
);
}
}

View File

@ -6,6 +6,7 @@ import java.util.List;
import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
import io.github.wulkanowy.data.db.dao.entities.Day;
import io.github.wulkanowy.data.db.dao.entities.Diary;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.Subject;
import io.github.wulkanowy.data.db.dao.entities.TimetableLesson;
@ -17,8 +18,22 @@ public final class DataObjectConverter {
throw new IllegalStateException("Utility class");
}
public static List<Subject> subjectsToSubjectEntities(List<io.github.wulkanowy.api.grades.Subject> subjectList) {
public static List<Diary> diariesToDiaryEntities(List<io.github.wulkanowy.api.Diary> diaryList) {
List<Diary> diaryEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.Diary diary : diaryList) {
Diary diaryEntity = new Diary()
.setValue(diary.getId())
.setName(diary.getName())
.setStudentId(diary.getStudentId())
.setIsCurrent(diary.isCurrent());
diaryEntityList.add(diaryEntity);
}
return diaryEntityList;
}
public static List<Subject> subjectsToSubjectEntities(List<io.github.wulkanowy.api.grades.Subject> subjectList) {
List<Subject> subjectEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.grades.Subject subject : subjectList) {
@ -33,7 +48,6 @@ public final class DataObjectConverter {
}
public static List<Grade> gradesToGradeEntities(List<io.github.wulkanowy.api.grades.Grade> gradeList) {
List<Grade> gradeEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.grades.Grade grade : gradeList) {
@ -67,7 +81,6 @@ public final class DataObjectConverter {
public static List<Day> daysToDaysEntities(List<io.github.wulkanowy.api.generic.Day> dayList) {
List<Day> dayEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.generic.Day day : dayList) {
@ -110,7 +123,6 @@ public final class DataObjectConverter {
}
public static List<TimetableLesson> lessonsToTimetableLessonsEntities(List<io.github.wulkanowy.api.generic.Lesson> lessonList) {
List<TimetableLesson> lessonEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.generic.Lesson lesson : lessonList) {
@ -120,7 +132,6 @@ public final class DataObjectConverter {
}
public static List<AttendanceLesson> lessonsToAttendanceLessonsEntities(List<io.github.wulkanowy.api.generic.Lesson> lessonList) {
List<AttendanceLesson> lessonEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.generic.Lesson lesson : lessonList) {