Adding Log in / log out behavior
All checks were successful
Deploy Promiscuity Auth API / deploy (push) Successful in 57s
k8s smoke test / test (push) Successful in 5s

This commit is contained in:
hz 2025-11-23 09:41:26 -06:00
parent 59e33760ad
commit 85711e42cd
12 changed files with 267 additions and 27 deletions

7
README.txt Normal file
View File

@ -0,0 +1,7 @@
Auth Microservice swagger is accessible at https://pauth.ranaze.com/swagger/index.html
Test Users:
SUPER/SUPER - Super User
test1/test1 - Super User
test3/test3 - User

View File

@ -1,9 +0,0 @@
Perforce Connection String: ssl:perforce.ranaze.com:443
Git ↔ Perforce quick map
repo → depot (//depot/...)
branch → stream (e.g., //depot/main, //depot/alice)
clone → workspace/client (local view + metadata)
commit → changelist (pending → submitted)
PR/MR → shelve + review (with Swarm) or merge up from task stream
.gitignore → P4IGNORE file (e.g., .p4ignore)

View File

@ -23,6 +23,7 @@ bus_layout="res://audio/bus_layout.tres"
MenuMusic="*res://scenes/UI/menu_music.tscn"
MenuSfx="*res://scenes/UI/menu_sfx.tscn"
AuthState="*res://scenes/UI/auth_state.gd"
[dotnet]

View File

@ -0,0 +1,15 @@
extends Node
var is_logged_in: bool = false
var access_token: String = ""
var username: String = ""
func set_session(new_username: String, token: String) -> void:
is_logged_in = true
username = new_username
access_token = token
func clear_session() -> void:
is_logged_in = false
username = ""
access_token = ""

View File

@ -0,0 +1 @@
uid://ccloj2rh4dche

View File

@ -0,0 +1,48 @@
extends Control
const AUTH_LOGIN_URL := "https://pauth.ranaze.com/api/Auth/login"
@onready var _username_input: LineEdit = %UsernameInput
@onready var _password_input: LineEdit = %PasswordInput
@onready var _login_request: HTTPRequest = %LoginRequest
@onready var _error_label: Label = %ErrorLabel
func _on_log_in_button_pressed() -> void:
var username := _username_input.text.strip_edges()
var password := _password_input.text
if username.is_empty() or password.is_empty():
_show_error("Username and password required.")
return
var payload := {
"username": username,
"password": password,
}
var headers := PackedStringArray(["Content-Type: application/json"])
var err := _login_request.request(AUTH_LOGIN_URL, headers, HTTPClient.METHOD_POST, JSON.stringify(payload))
if err != OK:
_show_error("Failed to send login request.")
func _on_login_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
var body_text := body.get_string_from_utf8()
if result != HTTPRequest.RESULT_SUCCESS:
_show_error("Network error. Please try again.")
return
if response_code >= 200 and response_code < 300:
var response: Variant = JSON.parse_string(body_text)
if typeof(response) == TYPE_DICTIONARY:
#print("Login success for %s" % response.get("username", "unknown"))
#print("Access Token: %s" % response.get("accessToken", ""))
var token := String(response.get("accessToken", ""))
var username := String(response.get("username", ""))
AuthState.set_session(username, token)
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
else:
_show_error("Login failed. Check your credentials.")
func _on_back_button_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
func _show_error(message: String) -> void:
_error_label.text = message

View File

@ -0,0 +1 @@
uid://bnrhapdcfvp04

View File

@ -0,0 +1,117 @@
[gd_scene load_steps=5 format=3 uid="uid://fmp1tah03kew"]
[ext_resource type="Script" path="res://scenes/UI/login_screen.gd" id="1_jqkpi"]
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="2_2n6di"]
[ext_resource type="Theme" uid="uid://tn8qndst18d6" path="res://themes/title_font_theme.tres" id="3_c4k70"]
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="4_gx673"]
[node name="LoginScreen" 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_jqkpi")
[node name="TextureRect" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("2_2n6di")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 80
theme_override_constants/margin_top = 40
theme_override_constants/margin_right = 80
theme_override_constants/margin_bottom = 40
[node name="ContentCenter" type="CenterContainer" parent="MarginContainer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="ContentVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme_override_constants/separation = 24
[node name="TitleLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("3_c4k70")
text = "ACCOUNT LOGIN"
horizontal_alignment = 1
[node name="FormVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
layout_mode = 2
size_flags_horizontal = 4
theme_override_constants/separation = 8
custom_minimum_size = Vector2(480, 0)
[node name="UsernameLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
layout_mode = 2
text = "Username"
[node name="UsernameInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
unique_name_in_owner = true
layout_mode = 2
placeholder_text = "enter username"
caret_blink = true
[node name="PasswordLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
layout_mode = 2
text = "Password"
[node name="PasswordInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
unique_name_in_owner = true
layout_mode = 2
placeholder_text = "enter password"
secret = true
[node name="ButtonVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
layout_mode = 2
size_flags_horizontal = 4
theme_override_constants/separation = 12
[node name="ErrorLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
unique_name_in_owner = true
layout_mode = 2
theme = ExtResource("3_c4k70")
horizontal_alignment = 1
theme_override_font_sizes/font_size = 26
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
[node name="LogInButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("4_gx673")
text = "LOG IN"
text_alignment = 1
[node name="BackButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("4_gx673")
text = "BACK"
text_alignment = 1
[node name="LoginRequest" type="HTTPRequest" parent="."]
unique_name_in_owner = true
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ButtonVBox/LogInButton" to="." method="_on_log_in_button_pressed"]
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ButtonVBox/BackButton" to="." method="_on_back_button_pressed"]
[connection signal="request_completed" from="LoginRequest" to="." method="_on_login_request_completed"]

View File

@ -3,6 +3,7 @@ extends AudioStreamPlayer
const MENU_SCENES: Dictionary = {
"res://scenes/UI/start_screen.tscn": true,
"res://scenes/UI/Settings.tscn": true,
"res://scenes/UI/login_screen.tscn": true,
}
const CONFIG_PATH := "user://settings.cfg"

View File

@ -1,10 +1,16 @@
extends Control
const AUTH_LOGOUT_URL := "https://pauth.ranaze.com/api/Auth/logout"
@onready var _login_button: Button = $MarginContainer/CenterContainer/ContentVBox/VBoxContainer/LogInButton
@onready var _logout_request: HTTPRequest = %LogoutRequest
func _ready():
_register_focus_sounds()
_update_login_button()
func _register_focus_sounds() -> void:
var button_container := $MarginContainer/MarginContainer/VBoxContainer
var button_container := $MarginContainer/CenterContainer/ContentVBox/VBoxContainer
for child in button_container.get_children():
if child is BaseButton:
var button: BaseButton = child
@ -22,6 +28,39 @@ func _on_settings_button_pressed():
func _on_quit_button_pressed():
get_tree().quit()
func _on_log_in_button_pressed():
if AuthState.is_logged_in:
_request_logout()
else:
get_tree().change_scene_to_file("res://scenes/UI/login_screen.tscn")
func _on_menu_item_focus() -> void:
if MenuSfx:
MenuSfx.play_hover()
func _request_logout() -> void:
if AuthState.access_token.is_empty():
AuthState.clear_session()
_update_login_button()
return
var headers := PackedStringArray([
"Authorization: Bearer %s" % AuthState.access_token,
])
var err := _logout_request.request(AUTH_LOGOUT_URL, headers, HTTPClient.METHOD_POST)
if err != OK:
push_warning("Failed to send logout request: %s" % err)
AuthState.clear_session()
_update_login_button()
func _on_logout_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
var body_text := body.get_string_from_utf8()
if result != HTTPRequest.RESULT_SUCCESS or response_code < 200 or response_code >= 300:
push_warning("Logout failed (%s/%s): %s" % [result, response_code, body_text])
AuthState.clear_session()
_update_login_button()
func _update_login_button() -> void:
if AuthState.is_logged_in:
_login_button.text = "LOG OUT"
else:
_login_button.text = "LOG IN"

View File

@ -4,6 +4,7 @@
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="1_tx5wa"]
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="2_r2jwc"]
[ext_resource type="Theme" uid="uid://tn8qndst18d6" path="res://themes/title_font_theme.tres" id="4_hm208"]
[node name="StartScreen" type="Control"]
layout_mode = 3
anchors_preset = 15
@ -34,7 +35,16 @@ theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="Label" type="Label" parent="MarginContainer"]
[node name="CenterContainer" type="CenterContainer" parent="MarginContainer"]
layout_mode = 2
[node name="ContentVBox" type="VBoxContainer" parent="MarginContainer/CenterContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
theme_override_constants/separation = 10
[node name="Label" type="Label" parent="MarginContainer/CenterContainer/ContentVBox"]
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("4_hm208")
@ -42,40 +52,49 @@ text = "PROJECT
PROMISCUOUS"
horizontal_alignment = 1
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"]
[node name="TitleSpacer" type="Control" parent="MarginContainer/CenterContainer/ContentVBox"]
custom_minimum_size = Vector2(0, 40)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
theme_override_constants/margin_top = 10
theme_override_constants/margin_bottom = 60
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/MarginContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/CenterContainer/ContentVBox"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
theme_override_constants/separation = 6
[node name="StartButton" type="Button" parent="MarginContainer/MarginContainer/VBoxContainer"]
[node name="LogInButton" type="Button" parent="MarginContainer/CenterContainer/ContentVBox/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_horizontal = 4
size_flags_vertical = 4
theme = ExtResource("1_tx5wa")
text = "LOG IN"
[node name="StartButton" type="Button" parent="MarginContainer/CenterContainer/ContentVBox/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme = ExtResource("1_tx5wa")
text = "START"
[node name="SettingsButton" type="Button" parent="MarginContainer/MarginContainer/VBoxContainer"]
[node name="SettingsButton" type="Button" parent="MarginContainer/CenterContainer/ContentVBox/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme = ExtResource("1_tx5wa")
text = "SETTINGS"
[node name="QuitButton" type="Button" parent="MarginContainer/MarginContainer/VBoxContainer"]
[node name="QuitButton" type="Button" parent="MarginContainer/CenterContainer/ContentVBox/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme = ExtResource("1_tx5wa")
text = "QUIT"
[connection signal="pressed" from="MarginContainer/MarginContainer/VBoxContainer/StartButton" to="." method="_on_start_button_pressed"]
[connection signal="pressed" from="MarginContainer/MarginContainer/VBoxContainer/SettingsButton" to="." method="_on_settings_button_pressed"]
[connection signal="pressed" from="MarginContainer/MarginContainer/VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"]
[node name="LogoutRequest" type="HTTPRequest" parent="."]
unique_name_in_owner = true
[connection signal="pressed" from="MarginContainer/CenterContainer/ContentVBox/VBoxContainer/LogInButton" to="." method="_on_log_in_button_pressed"]
[connection signal="pressed" from="MarginContainer/CenterContainer/ContentVBox/VBoxContainer/StartButton" to="." method="_on_start_button_pressed"]
[connection signal="pressed" from="MarginContainer/CenterContainer/ContentVBox/VBoxContainer/SettingsButton" to="." method="_on_settings_button_pressed"]
[connection signal="pressed" from="MarginContainer/CenterContainer/ContentVBox/VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"]
[connection signal="request_completed" from="LogoutRequest" to="." method="_on_logout_request_completed"]

View File

@ -1,7 +1,7 @@
{
"Kestrel": { "Endpoints": { "Http": { "Url": "http://0.0.0.0:5000" } } },
"MongoDB": { "ConnectionString": "mongodb://192.168.86.50:27017", "DatabaseName": "GameDb" },
"Jwt": { "Key": "SuperUltraSecureJwtKeyWithAtLeast32Chars!!", "Issuer": "GameAuthApi", "Audience": "game-auth-api" },
"MongoDB": { "ConnectionString": "mongodb://192.168.86.50:27017", "DatabaseName": "promiscuity" },
"Jwt": { "Key": "SuperUltraSecureJwtKeyWithAtLeast32Chars!!", "Issuer": "promiscuity", "Audience": "promiscuity-auth-api" },
"Logging": { "LogLevel": { "Default": "Information" } },
"AllowedHosts": "*"
}