ASP.NET Core 2.0 开源Git HTTP Server

来源:互联网 发布:脸部黄金比例测试软件 编辑:程序博客网 时间:2024/05/14 02:43
ASP.NET Core 2.0 开源Git HTTP Server,实现类似 GitHub、GitLab。


GitHub:https://github.com/linezero/GitServer


设置


  "GitSettings": {
    "BasePath": "D:\\Git",
    "GitPath": "git"
  }
需要先安装Git,并确保git 命令可以执行,GitPath 可以是 git 的绝对路径。


目前实现的功能


创建仓库
浏览仓库
git客户端push pull
数据库支持 SQLite、MSSQL、MySQL
支持用户管理仓库
更多功能可以查看readme,也欢迎大家贡献支持。


Git交互
LibGit2Sharp 用于操作Git库,实现创建读取仓库信息及删除仓库。


以下是主要代码:


复制代码
        public Repository CreateRepository(string name)
        {
            string path = Path.Combine(Settings.BasePath, name);
            Repository repo = new Repository(Repository.Init(path, true));
            return repo;
        }


        public Repository CreateRepository(string name, string remoteUrl)
        {
            var path = Path.Combine(Settings.BasePath, name);
            try
            {
                using (var repo = new Repository(Repository.Init(path, true)))
                {
                    repo.Config.Set("core.logallrefupdates", true);
                    repo.Network.Remotes.Add("origin", remoteUrl, "+refs/*:refs/*");
                    var logMessage = "";
                    foreach (var remote in repo.Network.Remotes)
                    {
                        IEnumerable<string> refSpecs = remote.FetchRefSpecs.Select(x => x.Specification);
                        Commands.Fetch(repo, remote.Name, refSpecs, null, logMessage);
                    }
                    return repo;
                }                
            }
            catch
            {
                try
                {
                    Directory.Delete(path, true);
                }
                catch { }
                return null;
            }
        }


        public void DeleteRepository(string name)
        {
            Exception e = null;
            for(int i = 0; i < 3; i++)
            {
                try
                {
                    string path = Path.Combine(Settings.BasePath, name);
                    Directory.Delete(path, true);


                }
                catch(Exception ex) { e = ex; }
            }


            if (e != null)
                throw new GitException("Failed to delete repository", e);
        }
复制代码
 


执行Git命令


git-upload-pack 


git-receive-pack


主要代码 GitCommandResult 实现IActionResult


复制代码
public async Task ExecuteResultAsync(ActionContext context)
        {
            HttpResponse response = context.HttpContext.Response;
            Stream responseStream = GetOutputStream(context.HttpContext);


            string contentType = $"application/x-{Options.Service}";
            if (Options.AdvertiseRefs)
                contentType += "-advertisement";


            response.ContentType = contentType;


            response.Headers.Add("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
            response.Headers.Add("Pragma", "no-cache");
            response.Headers.Add("Cache-Control", "no-cache, max-age=0, must-revalidate");


            ProcessStartInfo info = new ProcessStartInfo(_gitPath, Options.ToString())
            {
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };


            using (Process process = Process.Start(info))
            {
                GetInputStream(context.HttpContext).CopyTo(process.StandardInput.BaseStream);


                if (Options.EndStreamWithNull)
                    process.StandardInput.Write('\0');
                process.StandardInput.Dispose();


                using (StreamWriter writer = new StreamWriter(responseStream))
                {
                    if (Options.AdvertiseRefs)
                    {
                        string service = $"# service={Options.Service}\n";
                        writer.Write($"{service.Length + 4:x4}{service}0000");
                        writer.Flush();
                    }


                    process.StandardOutput.BaseStream.www.huanggua130.cn CopyTo(responseStream);
                }


                process.WaitForExit();
            }
        }
复制代码
 


BasicAuthentication 基本认证实现
git http 默认的认证为Basic 基本认证,所以这里实现Basic 基本认证。


在ASP.NET Core 2.0 中 Authentication 变化很大之前1.0的一些代码是无法使用。


首先实现 AuthenticationHandler,然后实现  AuthenticationSchemeOptions,创建 BasicAuthenticationOptions。


最主要就是这两个类,下面两个类为辅助类,用于配置和中间件注册。


更多可以查看官方文档


身份验证


https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/


https://docs.microsoft.com/zh-cn/aspnet/core/migration/1x-to-2x/identity-2x


 View Code
 


CookieAuthentication Cookie认证
实现自定义登录,无需identity ,实现注册登录。


主要代码:


启用Cookie


https://github.com/linezero/GitServer/blob/master/GitServer/Startup.cs#L60


复制代码
services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(options=> {
                options.AccessDeniedPath = " www.yongshi123.cn /User/Login";
                options.LoginPath = "/User/Login";
            })
复制代码
登录


https://github.com/linezero/GitServer/blob/master/GitServer/Controllers/UserController.cs#L34


                    var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
                    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Name));
                    identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
                    identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
                    var principal = new ClaimsPrincipal(identity);
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
官方文档介绍:https://docs.microsoft.com/zh-cn/aspnet/www.huihuang178.cn core/security/authentication/cookie?tabs=aspnetcore2x


部署说明
发布后配置数据库及git目录(可以为绝对地址和命令)、git 仓库目录。


复制代码
{
  "ConnectionStrings": {
    "ConnectionType": "Sqlite", //Sqlite,MSSQL,MySQL
    "DefaultConnection": "Filename=gitserver.db"
  },
  "GitSettings": {
    "BasePath": "D:\\Git",
    "GitPath": "git"
  }
}
复制代码
运行后注册账户,登录账户创建仓库,然后根据提示操作,随后git push、git pull 都可以
原创粉丝点击