feat: update README to reflect completion of OAuth 2.0 authentication with browser flow
This commit is contained in:
@@ -346,7 +346,7 @@ This allows you to:
|
||||
- [ ] Material color application to models
|
||||
- [ ] Texture loading and mapping
|
||||
|
||||
### Phase 3: Network & Protocol (In Progress)
|
||||
### Phase 3: Network & Protocol ✅ MOSTLY COMPLETE
|
||||
- [x] Domain connection via UDP
|
||||
- [x] NLPacket protocol implementation
|
||||
- [x] DomainConnectRequest / DomainList handshake
|
||||
@@ -356,9 +356,10 @@ This allows you to:
|
||||
- [x] Session UUID generation
|
||||
- [x] Protocol signature verification (MD5)
|
||||
- [x] Domain address parsing (host:port/position/orientation)
|
||||
- [ ] OAuth 2.0 authentication (infrastructure ready, needs web flow) ⏭️ NEXT
|
||||
- [x] **OAuth 2.0 authentication with browser flow** 🎉
|
||||
- [x] Token persistence and refresh
|
||||
- [ ] Assignment client direct connections
|
||||
- [ ] Token persistence and refresh
|
||||
- [ ] Authenticated EntityServer queries
|
||||
|
||||
### Phase 4: Entity System (Current Focus)
|
||||
- [ ] Apply entity colors to model materials
|
||||
|
||||
142
src/OverteAuth.cpp.backup
Normal file
142
src/OverteAuth.cpp.backup
Normal file
@@ -0,0 +1,142 @@
|
||||
// OverteAuth.cpp
|
||||
#include "OverteAuth.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
#include <curl/curl.h>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
OverteAuth::OverteAuth() {
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
}
|
||||
|
||||
OverteAuth::~OverteAuth() {
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
size_t OverteAuth::writeCallback(void* contents, size_t size, size_t nmemb, void* userp) {
|
||||
size_t totalSize = size * nmemb;
|
||||
std::string* response = static_cast<std::string*>(userp);
|
||||
response->append(static_cast<char*>(contents), totalSize);
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
std::string OverteAuth::extractJsonString(const std::string& json, const std::string& key) {
|
||||
// Simple JSON string extraction (not a full parser, but works for our needs)
|
||||
std::string searchKey = "\"" + key + "\"";
|
||||
size_t keyPos = json.find(searchKey);
|
||||
if (keyPos == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Find the opening quote after the colon
|
||||
size_t colonPos = json.find(':', keyPos);
|
||||
if (colonPos == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t quoteStart = json.find('"', colonPos);
|
||||
if (quoteStart == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Find the closing quote
|
||||
size_t quoteEnd = json.find('"', quoteStart + 1);
|
||||
if (quoteEnd == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return json.substr(quoteStart + 1, quoteEnd - quoteStart - 1);
|
||||
}
|
||||
|
||||
bool OverteAuth::login(const std::string& username, const std::string& password, const std::string& metaverseUrl) {
|
||||
m_metaverseUrl = metaverseUrl;
|
||||
m_username = username;
|
||||
|
||||
CURL* curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
std::cerr << "[OverteAuth] Failed to initialize CURL" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct OAuth token endpoint
|
||||
// From Overte AccountManager: /oauth/token path under metaverse server
|
||||
std::string tokenUrl = m_metaverseUrl;
|
||||
if (tokenUrl.back() == '/') {
|
||||
tokenUrl.pop_back();
|
||||
}
|
||||
tokenUrl += "/api/v1/token"; // Try API v1 endpoint
|
||||
|
||||
std::cout << "[OverteAuth] Token URL: " << tokenUrl << std::endl;
|
||||
|
||||
// Construct POST data
|
||||
std::ostringstream postData;
|
||||
postData << "grant_type=password";
|
||||
postData << "&username=" << username; // Should URL-encode but simple for now
|
||||
postData << "&password=" << password;
|
||||
postData << "&scope=owner";
|
||||
|
||||
std::string responseData;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, tokenUrl.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.str().c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Starworld/1.0");
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
// Set Content-Type header
|
||||
struct curl_slist* headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
CURLcode res = curl_easy_perform(curl);
|
||||
|
||||
long httpCode = 0;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
std::cerr << "[OverteAuth] Login failed: " << curl_easy_strerror(res) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (httpCode != 200) {
|
||||
std::cerr << "[OverteAuth] Login failed with HTTP " << httpCode << std::endl;
|
||||
std::cerr << "[OverteAuth] Response: " << responseData << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse JSON response
|
||||
m_accessToken = extractJsonString(responseData, "access_token");
|
||||
m_refreshToken = extractJsonString(responseData, "refresh_token");
|
||||
|
||||
if (m_accessToken.empty()) {
|
||||
std::cerr << "[OverteAuth] No access token in response" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set expiration time (default to 1 hour if not specified)
|
||||
auto now = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
|
||||
m_tokenExpiresAt = now + 3600;
|
||||
|
||||
std::cout << "[OverteAuth] Successfully authenticated as " << username << std::endl;
|
||||
std::cout << "[OverteAuth] Access token: " << m_accessToken.substr(0, 20) << "..." << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OverteAuth::logout() {
|
||||
m_accessToken.clear();
|
||||
m_refreshToken.clear();
|
||||
m_username.clear();
|
||||
m_tokenExpiresAt = 0;
|
||||
|
||||
std::cout << "[OverteAuth] Logged out" << std::endl;
|
||||
}
|
||||
Reference in New Issue
Block a user