DEV Community

Cover image for Creating a Remote Git Hub for Your Company(Without Github)

Creating a Remote Git Hub for Your Company(Without Github)

Creating a Remote Git Hub for Your Company: A Comprehensive Guide

In this article, we'll explore how to create a remote Git hub for your company without relying on GitHub. We'll use TypeScript and Go for the backend implementation, integrate MySQL for data storage, and implement user authentication using FIDO2. This solution provides a secure and customizable alternative to third-party hosting platforms.

Backend Implementation

TypeScript Server

Let's start by setting up the TypeScript server to handle Git operations:

import express from 'express';
import { execSync } from 'child_process';

const app = express();
const port = 3000;

app.post('/create-repo', (req, res) => {
  const { repoName } = req.body;
  try {
    execSync(`git init --bare /path/to/repos/${repoName}.git`);
    res.status(200).json({ message: 'Repository created successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to create repository' });
  }
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});
Enter fullscreen mode Exit fullscreen mode

This TypeScript server provides an endpoint for creating new Git repositories on the server.

Go Git Server

Next, let's implement a Go server to handle Git push and pull operations:

package main

import (
    "fmt"
    "net/http"
    "os/exec"
)

func handleGitOperation(w http.ResponseWriter, r *http.Request) {
    repoPath := r.URL.Path[1:]
    gitCommand := r.Header.Get("X-Git-Command")

    cmd := exec.Command("git", gitCommand, "--stateless-rpc", repoPath)
    cmd.Stdin = r.Body
    cmd.Stdout = w
    cmd.Stderr = w

    if err := cmd.Run(); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}

func main() {
    http.HandleFunc("/", handleGitOperation)
    fmt.Println("Git server running on :8080")
    http.ListenAndServe(":8080", nil)
}
Enter fullscreen mode Exit fullscreen mode

This Go server handles Git push and pull operations by executing the appropriate Git commands.

Database Integration

To store repository metadata and user information, we'll use MySQL. Here's an example of how to set up the database connection and create tables:

import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host: 'localhost',
  user: 'your_username',
  password: 'your_password',
  database: 'git_hub',
});

async function createTables() {
  const connection = await pool.getConnection();
  try {
    await connection.query(`
      CREATE TABLE IF NOT EXISTS repositories (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        owner_id INT NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(255) NOT NULL,
        email VARCHAR(255) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
  } finally {
    connection.release();
  }
}

createTables();
Enter fullscreen mode Exit fullscreen mode

This code sets up the MySQL connection and creates tables for storing repository and user information.

User Authentication with FIDO2

Implementing FIDO2 authentication provides a secure, passwordless login experience. Here's a basic example of how to integrate FIDO2 authentication:

import { Fido2Lib } from 'fido2-lib';

const f2l = new Fido2Lib({
  timeout: 60000,
  rpId: 'your-company.com',
  rpName: 'Your Company Git Hub',
  challengeSize: 128,
  attestation: 'none',
  cryptoParams: [-7, -257],
});

app.post('/register', async (req, res) => {
  const { username, email } = req.body;
  const challengeResponse = await f2l.attestationOptions();
  // Store challenge and user info in the database
  res.json(challengeResponse);
});

app.post('/login', async (req, res) => {
  const { credential } = req.body;
  try {
    const result = await f2l.assertionResult(credential, {
      challenge: 'stored_challenge',
      origin: 'https://your-company.com',
      factor: 'either',
    });
    // Verify the result and create a session
    res.json({ success: true });
  } catch (error) {
    res.status(401).json({ error: 'Authentication failed' });
  }
});
Enter fullscreen mode Exit fullscreen mode

This code provides basic endpoints for FIDO2 registration and login. You'll need to implement additional logic to store and retrieve challenges and user credentials from the database.

Conclusion

By combining TypeScript and Go for the backend, MySQL for data storage, and FIDO2 for user authentication, you can create a robust and secure remote Git hub for your company. This solution offers full control over your source code and user management, without relying on third-party platforms like GitHub.

Remember to implement proper error handling, logging, and security measures in a production environment. Additionally, consider adding features like access control, code review processes, and integration with your existing development tools to create a comprehensive Git management solution tailored to your company's needs.

Top comments (3)

Collapse
 
mikeschinkel profile image
Mike Schinkel

Very interesting and useful article.

But why mix TypeScript and Go? Why not at least fully implement in both TypeScript and Go? I expect anyone wanting to do this will either want to use TypeScript or Go, but not both.

Collapse
 
devhindo profile image
devhindo

Why not creating everything in Go or TypeScript ? Why using two languages instead of simply using one ? seems a bit odd to me

Collapse
 
programmerraja profile image
Boopathi

This is a great overview of building a self-hosted Git solution! The breakdown of technologies is helpful. I'm especially interested in the FIDO2 implementation for security.