-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJsonConfig.cs
169 lines (141 loc) · 6.54 KB
/
JsonConfig.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Copyright (c) iQubit Inc. All rights reserved.
// Use of this source code is governed by a GPL-v3 license
namespace SCMApp {
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Text.Json;
/// <summary>
/// Credentials Related
/// Provides
/// - signature for commits
/// - identity for pushes
/// - provide commit log file path
/// - performs some validation checks
/// </summary>
class JsonConfig {
private UserCredential UserCred {get; set; }
/// <summary>
/// Config file path
/// </summary>
private string JsonConfigFilePath { get; set; }
/// <summary>
/// Read and Parse Config file
///
/// <remarks>
/// <see href="https://docs.microsoft.com/en-us/dotnet/api/system.environment.specialfolder">
/// Accessing Local App Data via Environment
/// </see>
/// </remarks>
/// <param name="fullNameFromRepo">Full Name in Repo Config</param>
/// <param name="emailFromRepo">Email Address in Repo Config</param>
/// <param name="repoPath">Repository Dir/Path</param>
public JsonConfig(string jsonConfigurationFilePath, string fullNameFromRepo, string emailFromRepo, string repoPath) {
JsonConfigFilePath = jsonConfigurationFilePath;
if (JsonConfigFilePath == string.Empty)
JsonConfigFilePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
+ @"\GitUtilConfig.json";
if (!System.IO.File.Exists(JsonConfigFilePath)) {
throw new InvalidOperationException($"Required config: {JsonConfigFilePath} not found!" +
"Please create the config file and run this application again.");
}
UserCred = new UserCredential();
using System.IO.FileStream openStream = System.IO.File.OpenRead(JsonConfigFilePath);
// Since we're in constructor we cannot use async. Otherwise `DeserializeAsync`
var rootElement = JsonSerializer.Deserialize<JsonElement>(openStream);
// find account to use; based on the dirList
var servicesJson = rootElement.GetProperty("services");
var services = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(servicesJson) ?? new Dictionary<string, JsonElement>();
foreach(var service in services) {
var SCAccountsJson = service.Value;
var SCAccounts = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(SCAccountsJson);
if (SCAccounts is not null)
foreach(var SCAccount in SCAccounts) {
JsonElement specifiedDirsJson;
if (SCAccount.Value.TryGetProperty("Dirs", out specifiedDirsJson)) {
var dirList = JsonSerializer.Deserialize<HashSet<string>>(specifiedDirsJson)?? new HashSet<string>();
if (dirList.Contains(repoPath)) {
UserCred.UserName = SCAccount.Key;
// Print selected user to help finding duplicate Dir Entries, in case they exist
UserCred.GithubToken = SCAccount.Value.GetProperty("GithubToken").GetString() ?? string.Empty;
UserCred.Email = SCAccount.Value.GetProperty("Email").GetString() ?? string.Empty;
UserCred.FullName = SCAccount.Value.GetProperty("FullName").GetString() ?? string.Empty;
UserCred.CommitLogFilePath = SCAccount.Value.GetProperty("CommitLogFilePath").GetString() ?? string.Empty;
UserCred.SCProvider = service.Key;
break;
}
}
}
if (UserCred.SCProvider != string.Empty)
break;
}
if (UserCred.SCProvider == string.Empty) {
// get default account
var appSettingsJson = rootElement.GetProperty("application");
var defaultSCProvider = appSettingsJson.GetProperty("SCProvider").GetString() ?? string.Empty;
var defaultUserName = appSettingsJson.GetProperty("UserName").GetString() ?? string.Empty;
var defaultService = services[defaultSCProvider];
var defaultAccount = defaultService.GetProperty(defaultUserName);
UserCred.UserName = defaultUserName;
UserCred.GithubToken = defaultAccount.GetProperty("GithubToken").GetString() ?? string.Empty;
UserCred.Email = defaultAccount.GetProperty("Email").GetString() ?? string.Empty;
UserCred.FullName = defaultAccount.GetProperty("FullName").GetString() ?? string.Empty;
UserCred.CommitLogFilePath = defaultAccount.GetProperty("CommitLogFilePath").GetString() ?? string.Empty;
UserCred.SCProvider = defaultSCProvider;
}
Console.WriteLine($"Selected account: {UserCred.UserName}");
if (fullNameFromRepo != UserCred.FullName || emailFromRepo != UserCred.Email)
throw new InvalidOperationException("Inavlid user name or email in git config!");
}
/// <summary>
/// Structure to read records from config file (json format)
/// </summary>
class UserCredential {
/// <summary>
/// Github user name for example, 'coolgeek'
/// </summary>
public string UserName { get; set; }
/// <summary>
/// Actual Name
/// <example> Esther Arkin </example>
/// </summary>
public string FullName { get; set; }
public string Email { get; set; }
public string GithubToken { get; set; }
public string CommitLogFilePath { get; set; }
public HashSet<string>? Dirs { get; set; }
/// <summary>
/// Source Control Provider
/// </summary>
public string SCProvider { get; set; }
public UserCredential() {
// mark that the variable doesn't have an account 'Loaded' into it yet
SCProvider = string.Empty;
UserName = string.Empty;
FullName = string.Empty;
Email = string.Empty;
GithubToken = string.Empty;
CommitLogFilePath = string.Empty;
Dirs = null;
}
}
/// <summary>
/// Construct CredentialsHandler for <code>Network.Push</code>
/// </summary>
/// <remarks>
/// <see href="https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to">
/// Read from json file MS Docs ref
/// </see>
/// </remarks>
/// <returns>LibGit2Sharp.CredentialsHandler</returns>
public LibGit2Sharp.Handlers.CredentialsHandler GetCredentials() {
return new LibGit2Sharp.Handlers.CredentialsHandler(
(url, usernameFromUrl, types) => new LibGit2Sharp.UsernamePasswordCredentials()
{
Username = UserCred.UserName,
Password = UserCred.GithubToken
});
}
public string GetCommitFilePath() => UserCred.CommitLogFilePath;
}
}