ASP.NET Core DotNetCore realize their GitHub open source GitServer

ASP.NET Core 2.0 open source Git HTTP Server, to achieve a similar GitHub, GitLab.

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

Set up

  "GitSettings": {
    "BasePath": "D:\\Git",
    "GitPath": "git" } 

Need to install Git, git commands can be executed and to ensure that, GitPath git may be the absolute path.

Currently implemented features

  • Creating a warehouse
  • Browse warehouse
  • git client push pull
  • Database supports SQLite, MSSQL, MySQL
  • Support user management warehouse

More features you can view the readme, also welcome to contribute support.

Git interaction

LibGit2Sharp for operating Git library that implements create and delete read warehouse information warehouse.

Here are the main codes:

Copy the code
        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);
        }
Copy the code

 

Git command execution

git-upload-pack 

git-receive-pack

The main code GitCommandResult achieve IActionResult

Copy the code
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.CopyTo(responseStream);
                }

                process.WaitForExit();
            }
        }
Copy the code

 

BasicAuthentication achieve basic authentication

git http default authentication basic authentication to Basic, so here Basic achieve basic certification.

1.0 is some code can not be used until significant changes Authentication in ASP.NET Core 2.0.

First realize AuthenticationHandler, then realized AuthenticationSchemeOptions, create BasicAuthenticationOptions.

The most important is that these two categories, the following two classes for secondary classes, used to configure and middleware registration.

More to view official documents

Authentication

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

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

Copy the code
 1    public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
 2     {
 3         public BasicAuthenticationHandler(IOptionsMonitor<BasicAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
 4             : base(options, logger, encoder, clock)
 5         { }
 6         protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
 7         {
 8             if (!Request.Headers.ContainsKey("Authorization"))
 9                 return AuthenticateResult.NoResult();
10 
11             string authHeader = Request.Headers["Authorization"];
12             if (!authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
13                 return AuthenticateResult.NoResult();
14 
15             string token = authHeader.Substring("Basic ".Length).Trim();
16             string credentialString = Encoding.UTF8.GetString(Convert.FromBase64String(token));
17             string[] credentials = credentialString.Split(':');
18 
19             if (credentials.Length != 2)
20                 return AuthenticateResult.Fail("More than two strings seperated by colons found");
21 
22             ClaimsPrincipal principal = await Options.SignInAsync(credentials[0], credentials[1]);
23 
24             if (principal != null)
25             {
26                 AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), BasicAuthenticationDefaults.AuthenticationScheme);
27                 return AuthenticateResult.Success(ticket);
28             }
29 
30             return AuthenticateResult.Fail("Wrong credentials supplied");
31         }
32         protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
33         {
34             Response.StatusCode = 403;
35             return base.HandleForbiddenAsync(properties);
36         }
37 
38         protected override Task HandleChallengeAsync(AuthenticationProperties properties)
39         {
40             Response.StatusCode = 401;
41             string headerValue = $"{BasicAuthenticationDefaults.AuthenticationScheme} realm=\"{Options.Realm}\"";
42             Response.Headers.Append(Microsoft.Net.Http.Headers.HeaderNames.WWWAuthenticate, headerValue);
43             return base.HandleChallengeAsync(properties);
44         }
45     }
46 
47     public class BasicAuthenticationOptions : AuthenticationSchemeOptions, IOptions<BasicAuthenticationOptions>
48     {
49         private string _realm;
50 
51         public IServiceCollection ServiceCollection { get; set; }
52         public BasicAuthenticationOptions Value => this;
53         public string Realm
54         {
55             get { return _realm; }
56             set
57             {
58                 _realm = value;
59             }
60         }
61 
62         public async Task<ClaimsPrincipal> SignInAsync(string userName, string password)
63         {
64             using (var serviceScope = ServiceCollection.BuildServiceProvider().CreateScope())
65             {
66                 var _user = serviceScope.ServiceProvider.GetService<IRepository<User>>();
67                 var user = _user.List(r => r.Name == userName && r.Password == password).FirstOrDefault();
68                 if (user == null)
69                     return null;
70                 var identity = new ClaimsIdentity(BasicAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
71                 identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
72                 var principal = new ClaimsPrincipal(identity);
73                 return principal;
74             }
75         }
76     }
77 
78     public static class BasicAuthenticationDefaults
79     {
80         public const string AuthenticationScheme = "Basic";
81     }
82     public static class BasicAuthenticationExtensions
83     {
84         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder)
85             => builder.AddBasic(BasicAuthenticationDefaults.AuthenticationScheme, _ => { _.ServiceCollection = builder.Services;_.Realm = "GitServer"; });
86 
87         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder, Action<BasicAuthenticationOptions> configureOptions)
88             => builder.AddBasic(BasicAuthenticationDefaults.AuthenticationScheme, configureOptions);
89 
90         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder, string authenticationScheme, Action<BasicAuthenticationOptions> configureOptions)
91             => builder.AddBasic(authenticationScheme, displayName: null, configureOptions: configureOptions);
92 
93         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<BasicAuthenticationOptions> configureOptions)
94         {
95             builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IOptions<BasicAuthenticationOptions>, BasicAuthenticationOptions>());
96             return builder.AddScheme<BasicAuthenticationOptions, BasicAuthenticationHandler>(authenticationScheme, displayName, configureOptions);
97         }
98     }
Copy the code

 

CookieAuthentication Cookie Authentication

Implementing custom login, no identity, log on to achieve registration.

The main code:

Enable Cookie

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

Copy the code
services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(options=> {
                options.AccessDeniedPath = "/User/Login";
                options.LoginPath = "/User/Login";
            })
Copy the code

log in

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);

Official document describes: https: //docs.microsoft.com/zh-cn/aspnet/core/security/authentication/cookie tabs = aspnetcore2x?

Deployment instructions

After the release configuration database and git directory (may be an absolute address and command), git repository directory.

Copy the code
{
  "ConnectionStrings": {
    "ConnectionType": "Sqlite", //Sqlite,MSSQL,MySQL
    "DefaultConnection": "Filename=gitserver.db"
  },
  "GitSettings": {
    "BasePath": "D:\\Git",
    "GitPath": "git"
  }
}
Copy the code

After running up an account login account creation warehouses, then follow the prompts, then git push, git pull can.

 

 
Category:  ASP.NET Core
Good text to the top  follow me  The paper collection   
9
0
 
 
 
<<  : Previous  .NET and .NET Core System Architecture
>>  Next Article:  Orchard Core one minute to build ASP.NET Core CMS

 

ASP.NET Core 2.0 open source Git HTTP Server, to achieve a similar GitHub, GitLab.

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

Set up

  "GitSettings": {
    "BasePath": "D:\\Git",
    "GitPath": "git" } 

Need to install Git, git commands can be executed and to ensure that, GitPath git may be the absolute path.

Currently implemented features

  • Creating a warehouse
  • Browse warehouse
  • git client push pull
  • Database supports SQLite, MSSQL, MySQL
  • Support user management warehouse

More features you can view the readme, also welcome to contribute support.

Git interaction

LibGit2Sharp for operating Git library that implements create and delete read warehouse information warehouse.

Here are the main codes:

Copy the code
        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);
        }
Copy the code

 

Git command execution

git-upload-pack 

git-receive-pack

The main code GitCommandResult achieve IActionResult

Copy the code
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.CopyTo(responseStream);
                }

                process.WaitForExit();
            }
        }
Copy the code

 

BasicAuthentication achieve basic authentication

git http default authentication basic authentication to Basic, so here Basic achieve basic certification.

1.0 is some code can not be used until significant changes Authentication in ASP.NET Core 2.0.

First realize AuthenticationHandler, then realized AuthenticationSchemeOptions, create BasicAuthenticationOptions.

The most important is that these two categories, the following two classes for secondary classes, used to configure and middleware registration.

More to view official documents

Authentication

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

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

Copy the code
 1    public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
 2     {
 3         public BasicAuthenticationHandler(IOptionsMonitor<BasicAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
 4             : base(options, logger, encoder, clock)
 5         { }
 6         protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
 7         {
 8             if (!Request.Headers.ContainsKey("Authorization"))
 9                 return AuthenticateResult.NoResult();
10 
11             string authHeader = Request.Headers["Authorization"];
12             if (!authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
13                 return AuthenticateResult.NoResult();
14 
15             string token = authHeader.Substring("Basic ".Length).Trim();
16             string credentialString = Encoding.UTF8.GetString(Convert.FromBase64String(token));
17             string[] credentials = credentialString.Split(':');
18 
19             if (credentials.Length != 2)
20                 return AuthenticateResult.Fail("More than two strings seperated by colons found");
21 
22             ClaimsPrincipal principal = await Options.SignInAsync(credentials[0], credentials[1]);
23 
24             if (principal != null)
25             {
26                 AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), BasicAuthenticationDefaults.AuthenticationScheme);
27                 return AuthenticateResult.Success(ticket);
28             }
29 
30             return AuthenticateResult.Fail("Wrong credentials supplied");
31         }
32         protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
33         {
34             Response.StatusCode = 403;
35             return base.HandleForbiddenAsync(properties);
36         }
37 
38         protected override Task HandleChallengeAsync(AuthenticationProperties properties)
39         {
40             Response.StatusCode = 401;
41             string headerValue = $"{BasicAuthenticationDefaults.AuthenticationScheme} realm=\"{Options.Realm}\"";
42             Response.Headers.Append(Microsoft.Net.Http.Headers.HeaderNames.WWWAuthenticate, headerValue);
43             return base.HandleChallengeAsync(properties);
44         }
45     }
46 
47     public class BasicAuthenticationOptions : AuthenticationSchemeOptions, IOptions<BasicAuthenticationOptions>
48     {
49         private string _realm;
50 
51         public IServiceCollection ServiceCollection { get; set; }
52         public BasicAuthenticationOptions Value => this;
53         public string Realm
54         {
55             get { return _realm; }
56             set
57             {
58                 _realm = value;
59             }
60         }
61 
62         public async Task<ClaimsPrincipal> SignInAsync(string userName, string password)
63         {
64             using (var serviceScope = ServiceCollection.BuildServiceProvider().CreateScope())
65             {
66                 var _user = serviceScope.ServiceProvider.GetService<IRepository<User>>();
67                 var user = _user.List(r => r.Name == userName && r.Password == password).FirstOrDefault();
68                 if (user == null)
69                     return null;
70                 var identity = new ClaimsIdentity(BasicAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
71                 identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
72                 var principal = new ClaimsPrincipal(identity);
73                 return principal;
74             }
75         }
76     }
77 
78     public static class BasicAuthenticationDefaults
79     {
80         public const string AuthenticationScheme = "Basic";
81     }
82     public static class BasicAuthenticationExtensions
83     {
84         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder)
85             => builder.AddBasic(BasicAuthenticationDefaults.AuthenticationScheme, _ => { _.ServiceCollection = builder.Services;_.Realm = "GitServer"; });
86 
87         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder, Action<BasicAuthenticationOptions> configureOptions)
88             => builder.AddBasic(BasicAuthenticationDefaults.AuthenticationScheme, configureOptions);
89 
90         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder, string authenticationScheme, Action<BasicAuthenticationOptions> configureOptions)
91             => builder.AddBasic(authenticationScheme, displayName: null, configureOptions: configureOptions);
92 
93         public static AuthenticationBuilder AddBasic(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<BasicAuthenticationOptions> configureOptions)
94         {
95             builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IOptions<BasicAuthenticationOptions>, BasicAuthenticationOptions>());
96             return builder.AddScheme<BasicAuthenticationOptions, BasicAuthenticationHandler>(authenticationScheme, displayName, configureOptions);
97         }
98     }
Copy the code

 

CookieAuthentication Cookie Authentication

Implementing custom login, no identity, log on to achieve registration.

The main code:

Enable Cookie

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

Copy the code
services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(options=> {
                options.AccessDeniedPath = "/User/Login";
                options.LoginPath = "/User/Login";
            })
Copy the code

log in

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);

Official document describes: https: //docs.microsoft.com/zh-cn/aspnet/core/security/authentication/cookie tabs = aspnetcore2x?

Deployment instructions

After the release configuration database and git directory (may be an absolute address and command), git repository directory.

Copy the code
{
  "ConnectionStrings": {
    "ConnectionType": "Sqlite", //Sqlite,MSSQL,MySQL
    "DefaultConnection": "Filename=gitserver.db"
  },
  "GitSettings": {
    "BasePath": "D:\\Git",
    "GitPath": "git"
  }
}
Copy the code

After running up an account login account creation warehouses, then follow the prompts, then git push, git pull can.

 

Guess you like

Origin www.cnblogs.com/webenh/p/11574332.html