Integrate register and login APIs
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
extends Control
|
||||
|
||||
@onready var button: Button = $Button
|
||||
|
||||
|
||||
func _on_button_pressed():
|
||||
var res = await ServerManager.login("sarrazyndylan@gmail.com", "kalulu")
|
||||
print(res)
|
||||
@@ -0,0 +1,29 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://4buyb18au5l5"]
|
||||
|
||||
[ext_resource type="Script" path="res://control.gd" id="1_hpsys"]
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_hpsys")
|
||||
|
||||
[node name="Button" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -6.0
|
||||
offset_top = -6.0
|
||||
offset_right = 6.0
|
||||
offset_bottom = 6.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
text = "LOGIN"
|
||||
|
||||
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
||||
Binary file not shown.
Binary file not shown.
@@ -28,6 +28,7 @@ buses/default_bus_layout="res://resources/audio_buses/main_audio_bus_layout.tres
|
||||
LessonLogger="*res://sources/utils/autoloads/lesson_logger.gd"
|
||||
Database="*res://sources/utils/autoloads/Database.gd"
|
||||
UserDataManager="*res://sources/utils/autoloads/user_data_manager.gd"
|
||||
ServerManager="*res://sources/utils/autoloads/ServerManager.tscn"
|
||||
MusicManager="*res://sources/utils/autoloads/music_manager.tscn"
|
||||
Validation="*res://addons/godot-form-validator/validation.gd"
|
||||
OpeningCurtain="*res://sources/utils/autoloads/opening_curtain.tscn"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -13,6 +13,10 @@ enum Level {
|
||||
@export var level : Level
|
||||
@export var age : int
|
||||
|
||||
|
||||
func _to_string():
|
||||
return "{Code: %s, Name: %s, Level: %s, Age: %d}" % [code, name, Level.keys()[level], age]
|
||||
func to_dict() -> Dictionary:
|
||||
return {
|
||||
"code": code,
|
||||
"name": name,
|
||||
"level": level,
|
||||
"age": age
|
||||
}
|
||||
|
||||
@@ -15,11 +15,32 @@ enum EducationMethod {
|
||||
|
||||
@export var account_type : AccountType
|
||||
@export var education_method : EducationMethod
|
||||
@export var devices_count : int
|
||||
var devices_count : int
|
||||
@export var students : Dictionary # int : Array[StudentData]
|
||||
@export var email : String
|
||||
@export var password : String # Temporary
|
||||
var password : String
|
||||
@export var token: String
|
||||
@export var last_modified: String
|
||||
|
||||
func update_from_dict(dict: Dictionary) -> void:
|
||||
account_type = dict.account_type
|
||||
education_method = dict.education_method
|
||||
email = dict.email
|
||||
token = dict.token
|
||||
last_modified = dict.last_modified
|
||||
|
||||
students.clear()
|
||||
for device: String in dict.students.keys():
|
||||
var device_students: Array[StudentData] = []
|
||||
for s: Dictionary in dict.students[device]:
|
||||
var student = StudentData.new()
|
||||
student.code = str(s.code)
|
||||
student.name = s.name
|
||||
student.age = s.age
|
||||
student.level = s.level
|
||||
device_students.append(student)
|
||||
|
||||
students[int(device)] = device_students
|
||||
|
||||
func get_new_code() -> String :
|
||||
var used_codes = []
|
||||
@@ -48,5 +69,18 @@ func get_students_count() -> int :
|
||||
|
||||
return count
|
||||
|
||||
func _to_string():
|
||||
return "{Account Type: %s, Education Method: %s, Devices count: %d, Students: %s, Email: %s, Password: %s}" % [AccountType.keys()[account_type], EducationMethod.keys()[education_method], devices_count, str(students), email, password]
|
||||
func to_dict() -> Dictionary:
|
||||
var dict = {
|
||||
"account_type": account_type,
|
||||
"email": email,
|
||||
"password": password,
|
||||
"education_method": education_method,
|
||||
}
|
||||
|
||||
dict["students"] = {}
|
||||
for device in students.keys():
|
||||
dict["students"][device] = []
|
||||
for s: StudentData in students[device]:
|
||||
dict["students"][device].append(s.to_dict())
|
||||
|
||||
return dict
|
||||
|
||||
@@ -56,8 +56,13 @@ func _on_validate_button_pressed() -> void:
|
||||
if not validator.validate():
|
||||
return
|
||||
|
||||
# Login
|
||||
if UserDataManager.login(account_type, email_field.text, password_field.text, int(device_id_field.value)):
|
||||
logged_in.emit()
|
||||
# Request server for login
|
||||
var res = await ServerManager.login(account_type, int(device_id_field.value), email_field.text, password_field.text)
|
||||
if res.code == 200:
|
||||
# Login
|
||||
if UserDataManager.login(res.body):
|
||||
logged_in.emit()
|
||||
else:
|
||||
login_message.visible = true
|
||||
else:
|
||||
login_message.visible = true
|
||||
|
||||
@@ -104,9 +104,15 @@ func _on_step_completed(step : Step):
|
||||
progress_bar.max_value = current_steps.size()
|
||||
|
||||
if progress_bar.value == current_steps.size()-1:
|
||||
if UserDataManager.register(register_data):
|
||||
get_tree().change_scene_to_file(next_scene_path)
|
||||
# Send register via API
|
||||
var res = await ServerManager.register(register_data.to_dict())
|
||||
if res.code == 200:
|
||||
register_data.last_modified = res.body.last_modified
|
||||
register_data.token = res.body.token
|
||||
if UserDataManager.register(register_data):
|
||||
get_tree().change_scene_to_file(next_scene_path)
|
||||
else:
|
||||
# TODO Add a popup that explains the error
|
||||
print("Impossible to register")
|
||||
else:
|
||||
_go_to_step(progress_bar.value+1)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
extends Step
|
||||
|
||||
@onready var api_email_field_error: Label = %APIEmailFieldError
|
||||
|
||||
func _on_validate_button_pressed():
|
||||
api_email_field_error.visible = false
|
||||
|
||||
# Validate the fields
|
||||
if not form_validator.validate():
|
||||
push_warning("Validation failed (" + str(self) + ")")
|
||||
return
|
||||
|
||||
# Writes data in object
|
||||
if not form_binder.write():
|
||||
push_warning("Impossible to write data in object (" + str(self) + ")")
|
||||
return
|
||||
|
||||
var res = await ServerManager.check_email(data.email)
|
||||
if res.code != 200:
|
||||
api_email_field_error.visible = true
|
||||
return
|
||||
|
||||
if _on_next():
|
||||
next.emit(self)
|
||||
@@ -1,6 +1,7 @@
|
||||
[gd_scene load_steps=15 format=3 uid="uid://cwqcybk5tvbly"]
|
||||
[gd_scene load_steps=16 format=3 uid="uid://cwqcybk5tvbly"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bxd3i06rqpxf0" path="res://sources/menus/register/steps/base_step.tscn" id="1_66bx5"]
|
||||
[ext_resource type="Script" path="res://sources/menus/register/steps/credentials_step.gd" id="2_mqaqr"]
|
||||
[ext_resource type="Script" path="res://addons/godot-form-validator/control_validator.gd" id="3_hblcf"]
|
||||
[ext_resource type="Script" path="res://addons/godot-form-validator/rules/required_rule.gd" id="4_4ltsd"]
|
||||
[ext_resource type="Script" path="res://addons/godot-form-validator/rules/email_rule.gd" id="5_cnymo"]
|
||||
@@ -41,6 +42,7 @@ skip_validation = false
|
||||
rules = Array[Resource("res://addons/godot-form-validator/rules/validator_rule.gd")]([SubResource("Resource_5jooi"), SubResource("Resource_104uy")])
|
||||
|
||||
[node name="CredentialsStep" instance=ExtResource("1_66bx5")]
|
||||
script = ExtResource("2_mqaqr")
|
||||
step_name = "credentials"
|
||||
question = "CREDENTIALS_PROMPT"
|
||||
|
||||
@@ -82,6 +84,14 @@ text = "Test"
|
||||
label_settings = ExtResource("7_sndyb")
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="APIEmailFieldError" type="Label" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/EmailContainer/VBoxContainer" index="2"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
text = "USED_EMAIL_ADDRESS"
|
||||
label_settings = ExtResource("7_sndyb")
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer" index="1"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 8
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://yk1u0ohwwgb3"]
|
||||
|
||||
[ext_resource type="Script" path="res://sources/utils/autoloads/server_manager.gd" id="1_n6vsh"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_dx825"]
|
||||
colors = PackedColorArray(0.2, 0.2, 0.2, 0.505882, 0.2, 0.2, 0.2, 0.505882)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_68deq"]
|
||||
gradient = SubResource("Gradient_dx825")
|
||||
|
||||
[node name="ServerManager" type="CanvasLayer"]
|
||||
script = ExtResource("1_n6vsh")
|
||||
|
||||
[node name="HTTPRequest" type="HTTPRequest" parent="."]
|
||||
timeout = 30.0
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
visible = false
|
||||
top_level = true
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 0
|
||||
texture = SubResource("GradientTexture1D_68deq")
|
||||
|
||||
[connection signal="request_completed" from="HTTPRequest" to="." method="_on_http_request_request_completed"]
|
||||
@@ -0,0 +1,78 @@
|
||||
extends CanvasLayer
|
||||
signal request_completed(code: int, body: Dictionary)
|
||||
|
||||
@onready var http_request: HTTPRequest = $HTTPRequest
|
||||
@onready var loading_rect: TextureRect = $TextureRect
|
||||
|
||||
# TODO Put in a file
|
||||
const URL: String = "https://uqkpbayw1k.execute-api.eu-west-3.amazonaws.com/dev/"
|
||||
|
||||
# Response from the last request
|
||||
var code: int
|
||||
var json: Dictionary
|
||||
|
||||
func check_email(email: String) -> Dictionary:
|
||||
await _get_request("checkemail", {"mail" : email})
|
||||
return _response()
|
||||
|
||||
func register(data: Dictionary) -> Dictionary:
|
||||
await _post_json_request("register", data)
|
||||
return _response()
|
||||
|
||||
func login(type: TeacherSettings.AccountType, device:int, mail: String, password: String) -> Dictionary:
|
||||
await _get_request("login", {"type":type, "device":device, "mail": mail, "password": password})
|
||||
return _response()
|
||||
|
||||
|
||||
#region Sender functions
|
||||
|
||||
func _response() -> Dictionary:
|
||||
return {
|
||||
"code" : code,
|
||||
"body" : json
|
||||
}
|
||||
|
||||
|
||||
func _get_request(URI: String, params: Dictionary) -> void:
|
||||
loading_rect.visible = true
|
||||
code = 0
|
||||
json = {}
|
||||
|
||||
var req: = URL + URI
|
||||
var is_first_param: bool = true
|
||||
for key in params.keys():
|
||||
if is_first_param:
|
||||
req += "?"
|
||||
is_first_param = false
|
||||
else:
|
||||
req += "&"
|
||||
req += str(key) + "=" + str(params[key])
|
||||
|
||||
if http_request.request(req) == 0:
|
||||
await request_completed
|
||||
|
||||
|
||||
func _post_json_request(URI: String, data: Dictionary) -> void:
|
||||
loading_rect.visible = true
|
||||
code = 0
|
||||
json = {}
|
||||
|
||||
var req: = URL + URI
|
||||
var headers: = ["Content-Type: application/json"]
|
||||
|
||||
var json = JSON.stringify(data)
|
||||
print(json)
|
||||
if http_request.request(req, headers, HTTPClient.METHOD_POST, json) == 0:
|
||||
await request_completed
|
||||
|
||||
#endregion
|
||||
|
||||
func _on_http_request_request_completed(result, response_code, headers, body):
|
||||
code = response_code
|
||||
print("Response received : " + str(code))
|
||||
print(headers)
|
||||
if body:
|
||||
json = JSON.parse_string(body.get_string_from_utf8())
|
||||
print(json)
|
||||
request_completed.emit(response_code, json)
|
||||
loading_rect.visible = false
|
||||
@@ -51,28 +51,41 @@ func register(register_settings : TeacherSettings) -> bool:
|
||||
|
||||
return true
|
||||
|
||||
func login(type : TeacherSettings.AccountType, teacher : String, password : String, device_id : int) -> bool:
|
||||
if not _device_settings or not teacher or not password or device_id == 0:
|
||||
# Allow the user to log-in from the server
|
||||
func login(infos: Dictionary) -> bool:
|
||||
if not _device_settings or not infos:
|
||||
return false
|
||||
|
||||
var path := _get_teacher_settings_path(teacher)
|
||||
|
||||
if not FileAccess.file_exists(path):
|
||||
if not infos.has("device_ID") or not infos.device_ID:
|
||||
return false
|
||||
|
||||
var temp_teacher_settings = load(path) as TeacherSettings
|
||||
|
||||
if not temp_teacher_settings or temp_teacher_settings.password != password or temp_teacher_settings.account_type != type or device_id not in temp_teacher_settings.students.keys():
|
||||
if not infos.has("email") or not infos.email:
|
||||
return false
|
||||
|
||||
# Handles teacher settings
|
||||
teacher_settings = temp_teacher_settings
|
||||
if not infos.has("account_type") or infos.account_type < 0 or infos.account_type > 1:
|
||||
return false
|
||||
|
||||
if not infos.has("token") or not infos.token:
|
||||
return false
|
||||
|
||||
# Handles device settings
|
||||
_device_settings.teacher = teacher
|
||||
_device_settings.device_id = device_id
|
||||
_device_settings.teacher = infos.email
|
||||
_device_settings.device_id = infos.device_ID
|
||||
_save_device_settings()
|
||||
|
||||
var path := get_teacher_settings_path()
|
||||
|
||||
# Create the folder locally if it doesn't exists
|
||||
if not FileAccess.file_exists(path):
|
||||
DirAccess.make_dir_recursive_absolute(get_teacher_folder())
|
||||
teacher_settings = TeacherSettings.new()
|
||||
else:
|
||||
teacher_settings = load(path) as TeacherSettings
|
||||
# TODO Check if the last_modified is more recent
|
||||
|
||||
teacher_settings.update_from_dict(infos)
|
||||
_save_teacher_settings()
|
||||
|
||||
return true
|
||||
|
||||
func logout() -> void:
|
||||
|
||||
Reference in New Issue
Block a user