This commit is contained in:
Márton Kiss
2023-05-26 21:25:00 +02:00
parent 9e3b805fdd
commit 1558794e93
528 changed files with 38239 additions and 37732 deletions

View File

@@ -1,82 +1,82 @@
import 'package:intl/intl.dart';
class KretaAPI {
// IDP API
static const login = BaseKreta.kretaIdp + KretaApiEndpoints.token;
static const nonce = BaseKreta.kretaIdp + KretaApiEndpoints.nonce;
static const clientId = "kreta-ellenorzo-mobile-android";
// ELLENORZO API
static String notes(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.notes;
static String events(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.events;
static String student(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.student;
static String grades(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.grades;
static String absences(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.absences;
static String groups(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.groups;
static String groupAverages(String iss, String uid) =>
BaseKreta.kreta(iss) + KretaApiEndpoints.groupAverages + "?oktatasiNevelesiFeladatUid=" + uid;
static String timetable(String iss, {DateTime? start, DateTime? end}) =>
BaseKreta.kreta(iss) +
KretaApiEndpoints.timetable +
(start != null && end != null ? "?datumTol=" + start.toUtc().toIso8601String() + "&datumIg=" + end.toUtc().toIso8601String() : "");
static String exams(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.exams;
static String homework(String iss, {DateTime? start, String? id}) =>
BaseKreta.kreta(iss) +
KretaApiEndpoints.homework +
(id != null ? "/$id" : "") +
(id == null && start != null ? "?datumTol=" + DateFormat('yyyy-MM-dd').format(start) : "");
static String capabilities(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.capabilities;
static String downloadHomeworkAttachments(String iss, String uid, String type) =>
BaseKreta.kreta(iss) + KretaApiEndpoints.downloadHomeworkAttachments(uid, type);
// ADMIN API
static const sendMessage = BaseKreta.kretaAdmin + KretaAdminEndpoints.sendMessage;
static String messages(String endpoint) => BaseKreta.kretaAdmin + KretaAdminEndpoints.messages(endpoint);
static String message(String id) => BaseKreta.kretaAdmin + KretaAdminEndpoints.message(id);
static const recipientCategories = BaseKreta.kretaAdmin + KretaAdminEndpoints.recipientCategories;
static const availableCategories = BaseKreta.kretaAdmin + KretaAdminEndpoints.availableCategories;
static const recipientsTeacher = BaseKreta.kretaAdmin + KretaAdminEndpoints.recipientsTeacher;
static const uploadAttachment = BaseKreta.kretaAdmin + KretaAdminEndpoints.uploadAttachment;
static String downloadAttachment(String id) => BaseKreta.kretaAdmin + KretaAdminEndpoints.downloadAttachment(id);
static const trashMessage = BaseKreta.kretaAdmin + KretaAdminEndpoints.trashMessage;
static const deleteMessage = BaseKreta.kretaAdmin + KretaAdminEndpoints.deleteMessage;
}
class BaseKreta {
static String kreta(String iss) => "https://$iss.e-kreta.hu";
static const kretaIdp = "https://idp.e-kreta.hu";
static const kretaAdmin = "https://eugyintezes.e-kreta.hu";
static const kretaFiles = "https://files.e-kreta.hu";
}
class KretaApiEndpoints {
static const token = "/connect/token";
static const nonce = "/nonce";
static const notes = "/ellenorzo/V3/Sajat/Feljegyzesek";
static const events = "/ellenorzo/V3/Sajat/FaliujsagElemek";
static const student = "/ellenorzo/V3/Sajat/TanuloAdatlap";
static const grades = "/ellenorzo/V3/Sajat/Ertekelesek";
static const absences = "/ellenorzo/V3/Sajat/Mulasztasok";
static const groups = "/ellenorzo/V3/Sajat/OsztalyCsoportok";
static const groupAverages = "/ellenorzo/V3/Sajat/Ertekelesek/Atlagok/OsztalyAtlagok";
static const timetable = "/ellenorzo/V3/Sajat/OrarendElemek";
static const exams = "/ellenorzo/V3/Sajat/BejelentettSzamonkeresek";
static const homework = "/ellenorzo/V3/Sajat/HaziFeladatok";
// static const homeworkDone = "/ellenorzo/V3/Sajat/HaziFeladatok/Megoldva"; // Removed from the API
static const capabilities = "/ellenorzo/V3/Sajat/Intezmenyek";
static String downloadHomeworkAttachments(String uid, String type) => "/ellenorzo/V3/Sajat/Csatolmany/$uid";
}
class KretaAdminEndpoints {
//static const messages = "/api/v1/kommunikacio/postaladaelemek/sajat";
static const sendMessage = "/api/v1/kommunikacio/uzenetek";
static String messages(String endpoint) => "/api/v1/kommunikacio/postaladaelemek/$endpoint";
static String message(String id) => "/api/v1/kommunikacio/postaladaelemek/$id";
static const recipientCategories = "/api/v1/adatszotarak/cimzetttipusok";
static const availableCategories = "/api/v1/kommunikacio/cimezhetotipusok";
static const recipientsTeacher = "/api/v1/kreta/alkalmazottak/tanar";
static const uploadAttachment = "/ideiglenesfajlok";
static String downloadAttachment(String id) => "/api/v1/dokumentumok/uzenetek/$id";
static const trashMessage = "/api/v1/kommunikacio/postaladaelemek/kuka";
static const deleteMessage = "/api/v1/kommunikacio/postaladaelemek/torles";
}
import 'package:intl/intl.dart';
class KretaAPI {
// IDP API
static const login = BaseKreta.kretaIdp + KretaApiEndpoints.token;
static const nonce = BaseKreta.kretaIdp + KretaApiEndpoints.nonce;
static const clientId = "kreta-ellenorzo-mobile-android";
// ELLENORZO API
static String notes(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.notes;
static String events(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.events;
static String student(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.student;
static String grades(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.grades;
static String absences(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.absences;
static String groups(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.groups;
static String groupAverages(String iss, String uid) =>
BaseKreta.kreta(iss) + KretaApiEndpoints.groupAverages + "?oktatasiNevelesiFeladatUid=" + uid;
static String timetable(String iss, {DateTime? start, DateTime? end}) =>
BaseKreta.kreta(iss) +
KretaApiEndpoints.timetable +
(start != null && end != null ? "?datumTol=" + start.toUtc().toIso8601String() + "&datumIg=" + end.toUtc().toIso8601String() : "");
static String exams(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.exams;
static String homework(String iss, {DateTime? start, String? id}) =>
BaseKreta.kreta(iss) +
KretaApiEndpoints.homework +
(id != null ? "/$id" : "") +
(id == null && start != null ? "?datumTol=" + DateFormat('yyyy-MM-dd').format(start) : "");
static String capabilities(String iss) => BaseKreta.kreta(iss) + KretaApiEndpoints.capabilities;
static String downloadHomeworkAttachments(String iss, String uid, String type) =>
BaseKreta.kreta(iss) + KretaApiEndpoints.downloadHomeworkAttachments(uid, type);
// ADMIN API
static const sendMessage = BaseKreta.kretaAdmin + KretaAdminEndpoints.sendMessage;
static String messages(String endpoint) => BaseKreta.kretaAdmin + KretaAdminEndpoints.messages(endpoint);
static String message(String id) => BaseKreta.kretaAdmin + KretaAdminEndpoints.message(id);
static const recipientCategories = BaseKreta.kretaAdmin + KretaAdminEndpoints.recipientCategories;
static const availableCategories = BaseKreta.kretaAdmin + KretaAdminEndpoints.availableCategories;
static const recipientsTeacher = BaseKreta.kretaAdmin + KretaAdminEndpoints.recipientsTeacher;
static const uploadAttachment = BaseKreta.kretaAdmin + KretaAdminEndpoints.uploadAttachment;
static String downloadAttachment(String id) => BaseKreta.kretaAdmin + KretaAdminEndpoints.downloadAttachment(id);
static const trashMessage = BaseKreta.kretaAdmin + KretaAdminEndpoints.trashMessage;
static const deleteMessage = BaseKreta.kretaAdmin + KretaAdminEndpoints.deleteMessage;
}
class BaseKreta {
static String kreta(String iss) => "https://$iss.e-kreta.hu";
static const kretaIdp = "https://idp.e-kreta.hu";
static const kretaAdmin = "https://eugyintezes.e-kreta.hu";
static const kretaFiles = "https://files.e-kreta.hu";
}
class KretaApiEndpoints {
static const token = "/connect/token";
static const nonce = "/nonce";
static const notes = "/ellenorzo/V3/Sajat/Feljegyzesek";
static const events = "/ellenorzo/V3/Sajat/FaliujsagElemek";
static const student = "/ellenorzo/V3/Sajat/TanuloAdatlap";
static const grades = "/ellenorzo/V3/Sajat/Ertekelesek";
static const absences = "/ellenorzo/V3/Sajat/Mulasztasok";
static const groups = "/ellenorzo/V3/Sajat/OsztalyCsoportok";
static const groupAverages = "/ellenorzo/V3/Sajat/Ertekelesek/Atlagok/OsztalyAtlagok";
static const timetable = "/ellenorzo/V3/Sajat/OrarendElemek";
static const exams = "/ellenorzo/V3/Sajat/BejelentettSzamonkeresek";
static const homework = "/ellenorzo/V3/Sajat/HaziFeladatok";
// static const homeworkDone = "/ellenorzo/V3/Sajat/HaziFeladatok/Megoldva"; // Removed from the API
static const capabilities = "/ellenorzo/V3/Sajat/Intezmenyek";
static String downloadHomeworkAttachments(String uid, String type) => "/ellenorzo/V3/Sajat/Csatolmany/$uid";
}
class KretaAdminEndpoints {
//static const messages = "/api/v1/kommunikacio/postaladaelemek/sajat";
static const sendMessage = "/api/v1/kommunikacio/uzenetek";
static String messages(String endpoint) => "/api/v1/kommunikacio/postaladaelemek/$endpoint";
static String message(String id) => "/api/v1/kommunikacio/postaladaelemek/$id";
static const recipientCategories = "/api/v1/adatszotarak/cimzetttipusok";
static const availableCategories = "/api/v1/kommunikacio/cimezhetotipusok";
static const recipientsTeacher = "/api/v1/kreta/alkalmazottak/tanar";
static const uploadAttachment = "/ideiglenesfajlok";
static String downloadAttachment(String id) => "/api/v1/dokumentumok/uzenetek/$id";
static const trashMessage = "/api/v1/kommunikacio/postaladaelemek/kuka";
static const deleteMessage = "/api/v1/kommunikacio/postaladaelemek/torles";
}

View File

@@ -1,193 +1,193 @@
// ignore_for_file: avoid_print
import 'dart:convert';
import 'dart:io';
import 'package:filcnaplo/api/login.dart';
import 'package:filcnaplo/api/nonce.dart';
import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/api/providers/status_provider.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/models/user.dart';
import 'package:filcnaplo/utils/jwt.dart';
import 'package:filcnaplo_kreta_api/client/api.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http;
import 'dart:async';
class KretaClient {
String? accessToken;
String? refreshToken;
String? idToken;
String? userAgent;
late http.Client client;
late final SettingsProvider _settings;
late final UserProvider _user;
late final StatusProvider _status;
KretaClient({
this.accessToken,
required SettingsProvider settings,
required UserProvider user,
required StatusProvider status,
}) : _settings = settings,
_user = user,
_status = status,
userAgent = settings.config.userAgent {
var ioclient = HttpClient();
ioclient.badCertificateCallback = _checkCerts;
client = http.IOClient(ioclient);
}
bool _checkCerts(X509Certificate cert, String host, int port) {
return _settings.developerMode;
}
Future<dynamic> getAPI(
String url, {
Map<String, String>? headers,
bool autoHeader = true,
bool json = true,
bool rawResponse = false,
}) async {
Map<String, String> headerMap;
if (rawResponse) json = false;
if (headers != null) {
headerMap = headers;
} else {
headerMap = {};
}
try {
http.Response? res;
for (int i = 0; i < 3; i++) {
if (autoHeader) {
if (!headerMap.containsKey("authorization") && accessToken != null) headerMap["authorization"] = "Bearer $accessToken";
if (!headerMap.containsKey("user-agent") && userAgent != null) headerMap["user-agent"] = "$userAgent";
}
res = await client.get(Uri.parse(url), headers: headerMap);
_status.triggerRequest(res);
if (res.statusCode == 401) {
await refreshLogin();
headerMap.remove("authorization");
} else {
break;
}
// Wait before retrying
await Future.delayed(const Duration(milliseconds: 500));
}
if (res == null) throw "Login error";
if (json) {
return jsonDecode(res.body);
} else if (rawResponse) {
return res.bodyBytes;
} else {
return res.body;
}
} on http.ClientException catch (error) {
print("ERROR: KretaClient.getAPI ($url) ClientException: ${error.message}");
} catch (error) {
print("ERROR: KretaClient.getAPI ($url) ${error.runtimeType}: $error");
}
}
Future<dynamic> postAPI(
String url, {
Map<String, String>? headers,
bool autoHeader = true,
bool json = true,
Object? body,
}) async {
Map<String, String> headerMap;
if (headers != null) {
headerMap = headers;
} else {
headerMap = {};
}
try {
http.Response? res;
for (int i = 0; i < 3; i++) {
if (autoHeader) {
if (!headerMap.containsKey("authorization") && accessToken != null) headerMap["authorization"] = "Bearer $accessToken";
if (!headerMap.containsKey("user-agent") && userAgent != null) headerMap["user-agent"] = "$userAgent";
if (!headerMap.containsKey("content-type")) headerMap["content-type"] = "application/json";
}
res = await client.post(Uri.parse(url), headers: headerMap, body: body);
if (res.statusCode == 401) {
await refreshLogin();
headerMap.remove("authorization");
} else {
break;
}
}
if (res == null) throw "Login error";
if (json) {
return jsonDecode(res.body);
} else {
return res.body;
}
} on http.ClientException catch (error) {
print("ERROR: KretaClient.getAPI ($url) ClientException: ${error.message}");
} catch (error) {
print("ERROR: KretaClient.getAPI ($url) ${error.runtimeType}: $error");
}
}
Future<void> refreshLogin() async {
User? loginUser = _user.user;
if (loginUser == null) return;
Map<String, String> headers = {
"content-type": "application/x-www-form-urlencoded",
};
String nonceStr = await getAPI(KretaAPI.nonce, json: false);
Nonce nonce = getNonce(nonceStr, loginUser.username, loginUser.instituteCode);
headers.addAll(nonce.header());
if (_settings.presentationMode) {
print("DEBUG: refreshLogin: ${loginUser.id}");
} else {
print("DEBUG: refreshLogin: ${loginUser.id} ${loginUser.name}");
}
Map? loginRes = await postAPI(KretaAPI.login,
headers: headers,
body: User.loginBody(
username: loginUser.username,
password: loginUser.password,
instituteCode: loginUser.instituteCode,
));
if (loginRes != null) {
if (loginRes.containsKey("access_token")) accessToken = loginRes["access_token"];
if (loginRes.containsKey("refresh_token")) refreshToken = loginRes["refresh_token"];
// Update role
loginUser.role = JwtUtils.getRoleFromJWT(accessToken ?? "") ?? Role.student;
}
if (refreshToken != null) {
Map? refreshRes = await postAPI(KretaAPI.login,
headers: headers, body: User.refreshBody(refreshToken: refreshToken!, instituteCode: loginUser.instituteCode));
if (refreshRes != null) {
if (refreshRes.containsKey("id_token")) idToken = refreshRes["id_token"];
}
}
}
}
// ignore_for_file: avoid_print
import 'dart:convert';
import 'dart:io';
import 'package:filcnaplo/api/login.dart';
import 'package:filcnaplo/api/nonce.dart';
import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/api/providers/status_provider.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/models/user.dart';
import 'package:filcnaplo/utils/jwt.dart';
import 'package:filcnaplo_kreta_api/client/api.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http;
import 'dart:async';
class KretaClient {
String? accessToken;
String? refreshToken;
String? idToken;
String? userAgent;
late http.Client client;
late final SettingsProvider _settings;
late final UserProvider _user;
late final StatusProvider _status;
KretaClient({
this.accessToken,
required SettingsProvider settings,
required UserProvider user,
required StatusProvider status,
}) : _settings = settings,
_user = user,
_status = status,
userAgent = settings.config.userAgent {
var ioclient = HttpClient();
ioclient.badCertificateCallback = _checkCerts;
client = http.IOClient(ioclient);
}
bool _checkCerts(X509Certificate cert, String host, int port) {
return _settings.developerMode;
}
Future<dynamic> getAPI(
String url, {
Map<String, String>? headers,
bool autoHeader = true,
bool json = true,
bool rawResponse = false,
}) async {
Map<String, String> headerMap;
if (rawResponse) json = false;
if (headers != null) {
headerMap = headers;
} else {
headerMap = {};
}
try {
http.Response? res;
for (int i = 0; i < 3; i++) {
if (autoHeader) {
if (!headerMap.containsKey("authorization") && accessToken != null) headerMap["authorization"] = "Bearer $accessToken";
if (!headerMap.containsKey("user-agent") && userAgent != null) headerMap["user-agent"] = "$userAgent";
}
res = await client.get(Uri.parse(url), headers: headerMap);
_status.triggerRequest(res);
if (res.statusCode == 401) {
await refreshLogin();
headerMap.remove("authorization");
} else {
break;
}
// Wait before retrying
await Future.delayed(const Duration(milliseconds: 500));
}
if (res == null) throw "Login error";
if (json) {
return jsonDecode(res.body);
} else if (rawResponse) {
return res.bodyBytes;
} else {
return res.body;
}
} on http.ClientException catch (error) {
print("ERROR: KretaClient.getAPI ($url) ClientException: ${error.message}");
} catch (error) {
print("ERROR: KretaClient.getAPI ($url) ${error.runtimeType}: $error");
}
}
Future<dynamic> postAPI(
String url, {
Map<String, String>? headers,
bool autoHeader = true,
bool json = true,
Object? body,
}) async {
Map<String, String> headerMap;
if (headers != null) {
headerMap = headers;
} else {
headerMap = {};
}
try {
http.Response? res;
for (int i = 0; i < 3; i++) {
if (autoHeader) {
if (!headerMap.containsKey("authorization") && accessToken != null) headerMap["authorization"] = "Bearer $accessToken";
if (!headerMap.containsKey("user-agent") && userAgent != null) headerMap["user-agent"] = "$userAgent";
if (!headerMap.containsKey("content-type")) headerMap["content-type"] = "application/json";
}
res = await client.post(Uri.parse(url), headers: headerMap, body: body);
if (res.statusCode == 401) {
await refreshLogin();
headerMap.remove("authorization");
} else {
break;
}
}
if (res == null) throw "Login error";
if (json) {
return jsonDecode(res.body);
} else {
return res.body;
}
} on http.ClientException catch (error) {
print("ERROR: KretaClient.getAPI ($url) ClientException: ${error.message}");
} catch (error) {
print("ERROR: KretaClient.getAPI ($url) ${error.runtimeType}: $error");
}
}
Future<void> refreshLogin() async {
User? loginUser = _user.user;
if (loginUser == null) return;
Map<String, String> headers = {
"content-type": "application/x-www-form-urlencoded",
};
String nonceStr = await getAPI(KretaAPI.nonce, json: false);
Nonce nonce = getNonce(nonceStr, loginUser.username, loginUser.instituteCode);
headers.addAll(nonce.header());
if (_settings.presentationMode) {
print("DEBUG: refreshLogin: ${loginUser.id}");
} else {
print("DEBUG: refreshLogin: ${loginUser.id} ${loginUser.name}");
}
Map? loginRes = await postAPI(KretaAPI.login,
headers: headers,
body: User.loginBody(
username: loginUser.username,
password: loginUser.password,
instituteCode: loginUser.instituteCode,
));
if (loginRes != null) {
if (loginRes.containsKey("access_token")) accessToken = loginRes["access_token"];
if (loginRes.containsKey("refresh_token")) refreshToken = loginRes["refresh_token"];
// Update role
loginUser.role = JwtUtils.getRoleFromJWT(accessToken ?? "") ?? Role.student;
}
if (refreshToken != null) {
Map? refreshRes = await postAPI(KretaAPI.login,
headers: headers, body: User.refreshBody(refreshToken: refreshToken!, instituteCode: loginUser.instituteCode));
if (refreshRes != null) {
if (refreshRes.containsKey("id_token")) idToken = refreshRes["id_token"];
}
}
}
}