...
This commit is contained in:
@@ -2,16 +2,6 @@
|
||||
|
||||
This guide provides detailed instructions on how to integrate Gitea authentication into your Hostbasket application.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Introduction](#introduction)
|
||||
2. [Prerequisites](#prerequisites)
|
||||
3. [Setting Up Gitea OAuth Application](#setting-up-gitea-oauth-application)
|
||||
4. [Configuring Hostbasket for Gitea Authentication](#configuring-hostbasket-for-gitea-authentication)
|
||||
5. [Implementing the OAuth Flow](#implementing-the-oauth-flow)
|
||||
6. [Testing the Integration](#testing-the-integration)
|
||||
7. [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Introduction
|
||||
|
||||
Gitea is a self-hosted Git service that provides a GitHub-like interface. By integrating Gitea authentication into your Hostbasket application, you can allow users to log in using their Gitea accounts, simplifying the authentication process and providing a seamless experience.
|
||||
@@ -27,7 +17,7 @@ Before you begin, ensure you have:
|
||||
## Setting Up Gitea OAuth Application
|
||||
|
||||
1. Log in to your Gitea instance as an administrator
|
||||
2. Navigate to **Site Administration** > **Applications**
|
||||
2. Navigate to **Site Administration** > **Integrations** > **Applications**
|
||||
3. Click **Create a New OAuth2 Application**
|
||||
4. Fill in the application details:
|
||||
- **Application Name**: Hostbasket
|
||||
@@ -96,11 +86,11 @@ impl GiteaOAuthConfig {
|
||||
.expect("Missing GITEA_CLIENT_SECRET environment variable");
|
||||
let instance_url = env::var("GITEA_INSTANCE_URL")
|
||||
.expect("Missing GITEA_INSTANCE_URL environment variable");
|
||||
|
||||
|
||||
// Create OAuth client
|
||||
let auth_url = format!("{}/login/oauth/authorize", instance_url);
|
||||
let token_url = format!("{}/login/oauth/access_token", instance_url);
|
||||
|
||||
|
||||
let client = BasicClient::new(
|
||||
ClientId::new(client_id),
|
||||
Some(ClientSecret::new(client_secret)),
|
||||
@@ -110,7 +100,7 @@ impl GiteaOAuthConfig {
|
||||
.set_redirect_uri(
|
||||
RedirectUrl::new("http://localhost:9999/auth/gitea/callback".to_string()).unwrap(),
|
||||
);
|
||||
|
||||
|
||||
Self {
|
||||
client,
|
||||
instance_url,
|
||||
@@ -158,16 +148,16 @@ impl GiteaAuthController {
|
||||
.add_scope(Scope::new("read:user".to_string()))
|
||||
.add_scope(Scope::new("user:email".to_string()))
|
||||
.url();
|
||||
|
||||
|
||||
// Store the CSRF token in the session
|
||||
session.insert("oauth_csrf_token", csrf_token.secret())?;
|
||||
|
||||
|
||||
// Redirect to the authorization URL
|
||||
Ok(HttpResponse::Found()
|
||||
.append_header((header::LOCATION, auth_url.to_string()))
|
||||
.finish())
|
||||
}
|
||||
|
||||
|
||||
// Handle the OAuth callback
|
||||
pub async fn callback(
|
||||
oauth_config: web::Data<GiteaOAuthConfig>,
|
||||
@@ -177,11 +167,11 @@ impl GiteaAuthController {
|
||||
// Verify the CSRF token
|
||||
let csrf_token = session.get::<String>("oauth_csrf_token")?
|
||||
.ok_or_else(|| actix_web::error::ErrorBadRequest("Missing CSRF token"))?;
|
||||
|
||||
|
||||
if csrf_token != query.state {
|
||||
return Err(actix_web::error::ErrorBadRequest("Invalid CSRF token"));
|
||||
}
|
||||
|
||||
|
||||
// Exchange the authorization code for an access token
|
||||
let token = oauth_config
|
||||
.client
|
||||
@@ -189,11 +179,11 @@ impl GiteaAuthController {
|
||||
.request_async(oauth2::reqwest::async_http_client)
|
||||
.await
|
||||
.map_err(|e| actix_web::error::ErrorInternalServerError(format!("Token exchange error: {}", e)))?;
|
||||
|
||||
|
||||
// Get the user information from Gitea
|
||||
let client = Client::new();
|
||||
let user_info_url = format!("{}/api/v1/user", oauth_config.instance_url);
|
||||
|
||||
|
||||
let gitea_user = client
|
||||
.get(&user_info_url)
|
||||
.bearer_auth(token.access_token().secret())
|
||||
@@ -203,26 +193,26 @@ impl GiteaAuthController {
|
||||
.json::<crate::config::oauth::GiteaUser>()
|
||||
.await
|
||||
.map_err(|e| actix_web::error::ErrorInternalServerError(format!("JSON parsing error: {}", e)))?;
|
||||
|
||||
|
||||
// Create or update the user in your system
|
||||
let mut user = User::new(
|
||||
gitea_user.full_name.clone(),
|
||||
gitea_user.email.clone(),
|
||||
);
|
||||
|
||||
|
||||
// Set the user ID and role
|
||||
user.id = Some(gitea_user.id as i32);
|
||||
user.role = UserRole::User;
|
||||
|
||||
|
||||
// Generate JWT token
|
||||
let token = AuthController::generate_token(&user.email, &user.role)
|
||||
.map_err(|_| actix_web::error::ErrorInternalServerError("Failed to generate token"))?;
|
||||
|
||||
|
||||
// Store user data in session
|
||||
let user_json = serde_json::to_string(&user).unwrap();
|
||||
session.insert("user", &user_json)?;
|
||||
session.insert("auth_token", &token)?;
|
||||
|
||||
|
||||
// Create a cookie with the JWT token
|
||||
let cookie = Cookie::build("auth_token", token)
|
||||
.path("/")
|
||||
@@ -230,7 +220,7 @@ impl GiteaAuthController {
|
||||
.secure(false) // Set to true in production with HTTPS
|
||||
.max_age(actix_web::cookie::time::Duration::hours(24))
|
||||
.finish();
|
||||
|
||||
|
||||
// Redirect to the home page with JWT token in cookie
|
||||
Ok(HttpResponse::Found()
|
||||
.cookie(cookie)
|
||||
@@ -258,7 +248,7 @@ use crate::config::oauth::GiteaOAuthConfig;
|
||||
pub fn configure_routes(cfg: &mut web::ServiceConfig) {
|
||||
// Create the OAuth configuration
|
||||
let oauth_config = web::Data::new(GiteaOAuthConfig::new());
|
||||
|
||||
|
||||
// Configure session middleware with the consistent key
|
||||
let session_middleware = SessionMiddleware::builder(
|
||||
CookieSessionStore::default(),
|
||||
@@ -273,7 +263,7 @@ pub fn configure_routes(cfg: &mut web::ServiceConfig) {
|
||||
.wrap(session_middleware)
|
||||
.app_data(oauth_config.clone())
|
||||
// Existing routes...
|
||||
|
||||
|
||||
// Gitea OAuth routes
|
||||
.route("/auth/gitea", web::get().to(GiteaAuthController::login))
|
||||
.route("/auth/gitea/callback", web::get().to(GiteaAuthController::callback))
|
||||
@@ -310,9 +300,9 @@ Update your login page template (`src/views/auth/login.html`) to include a "Logi
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Login</button>
|
||||
</form>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<div class="text-center">
|
||||
<p>Or login with:</p>
|
||||
<a href="/auth/gitea" class="btn btn-secondary">
|
||||
|
Reference in New Issue
Block a user