build cli
parent
a9b809f5e5
commit
124f3092fb
@ -1,482 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using GetUsernameAsyncFunc=System.Func<System.Collections.Generic.IDictionary<string,string>, System.Threading.Tasks.Task<string>>;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc.Authentication
|
||||
{
|
||||
public class OAuthenticator
|
||||
{
|
||||
public OAuthenticator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
readonly string clientId;
|
||||
readonly string clientSecret;
|
||||
readonly string scope;
|
||||
readonly Uri authorizeUrl;
|
||||
readonly Uri accessTokenUrl;
|
||||
readonly Uri redirectUrl;
|
||||
readonly GetUsernameAsyncFunc getUsernameAsync;
|
||||
readonly string requestState;
|
||||
bool reportedForgery = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the client identifier.
|
||||
/// </summary>
|
||||
/// <value>The client identifier.</value>
|
||||
public string ClientId
|
||||
{
|
||||
get { return this.clientId; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the client secret.
|
||||
/// </summary>
|
||||
/// <value>The client secret.</value>
|
||||
public string ClientSecret
|
||||
{
|
||||
get { return this.clientSecret; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authorization scope.
|
||||
/// </summary>
|
||||
/// <value>The authorization scope.</value>
|
||||
public string Scope
|
||||
{
|
||||
get { return this.scope; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authorize URL.
|
||||
/// </summary>
|
||||
/// <value>The authorize URL.</value>
|
||||
public Uri AuthorizeUrl
|
||||
{
|
||||
get { return this.authorizeUrl; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the access token URL.
|
||||
/// </summary>
|
||||
/// <value>The URL used to request access tokens after an authorization code was received.</value>
|
||||
public Uri AccessTokenUrl
|
||||
{
|
||||
get { return this.accessTokenUrl; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect Url
|
||||
/// </summary>
|
||||
public Uri RedirectUrl
|
||||
{
|
||||
get { return this.redirectUrl; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="Yavsc.Authentication.YaOAuth2WebAuthenticator"/>
|
||||
/// that authenticates using implicit granting (token).
|
||||
/// </summary>
|
||||
/// <param name='clientId'>
|
||||
/// Client identifier.
|
||||
/// </param>
|
||||
/// <param name='scope'>
|
||||
/// Authorization scope.
|
||||
/// </param>
|
||||
/// <param name='authorizeUrl'>
|
||||
/// Authorize URL.
|
||||
/// </param>
|
||||
/// <param name='redirectUrl'>
|
||||
/// Redirect URL.
|
||||
/// </param>
|
||||
/// <param name='getUsernameAsync'>
|
||||
/// Method used to fetch the username of an account
|
||||
/// after it has been successfully authenticated.
|
||||
/// </param>
|
||||
public OAuthenticator(string clientId, string scope, Uri authorizeUrl, Uri redirectUrl, GetUsernameAsyncFunc getUsernameAsync = null)
|
||||
: this(redirectUrl)
|
||||
{
|
||||
if (string.IsNullOrEmpty(clientId))
|
||||
{
|
||||
throw new ArgumentException("clientId must be provided", "clientId");
|
||||
}
|
||||
if (authorizeUrl==null)
|
||||
throw new ArgumentNullException("authorizeUrl");
|
||||
|
||||
this.clientId = clientId;
|
||||
this.scope = scope ?? "";
|
||||
this.authorizeUrl = authorizeUrl ;
|
||||
this.getUsernameAsync = getUsernameAsync;
|
||||
this.accessTokenUrl = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance <see cref="ZicMoove.Droid.OAuth.YaOAuth2WebAuthenticator"/>
|
||||
/// that authenticates using authorization codes (code).
|
||||
/// </summary>
|
||||
/// <param name='clientId'>
|
||||
/// Client identifier.
|
||||
/// </param>
|
||||
/// <param name='clientSecret'>
|
||||
/// Client secret.
|
||||
/// </param>
|
||||
/// <param name='scope'>
|
||||
/// Authorization scope.
|
||||
/// </param>
|
||||
/// <param name='authorizeUrl'>
|
||||
/// Authorize URL.
|
||||
/// </param>
|
||||
/// <param name='redirectUrl'>
|
||||
/// Redirect URL.
|
||||
/// </param>
|
||||
/// <param name='accessTokenUrl'>
|
||||
/// URL used to request access tokens after an authorization code was received.
|
||||
/// </param>
|
||||
/// <param name='getUsernameAsync'>
|
||||
/// Method used to fetch the username of an account
|
||||
/// after it has been successfully authenticated.
|
||||
/// </param>
|
||||
public OAuthenticator(string clientId, string clientSecret, string scope, Uri authorizeUrl, Uri redirectUrl, Uri accessTokenUrl, GetUsernameAsyncFunc getUsernameAsync = null)
|
||||
: this(redirectUrl, clientSecret, accessTokenUrl)
|
||||
{
|
||||
if (string.IsNullOrEmpty(clientId))
|
||||
{
|
||||
throw new ArgumentException("clientId must be provided", "clientId");
|
||||
}
|
||||
this.clientId = clientId;
|
||||
|
||||
if (string.IsNullOrEmpty(clientSecret))
|
||||
{
|
||||
throw new ArgumentException("clientSecret must be provided", "clientSecret");
|
||||
}
|
||||
this.clientSecret = clientSecret;
|
||||
|
||||
this.scope = scope ?? "";
|
||||
|
||||
if (authorizeUrl == null)
|
||||
{
|
||||
throw new ArgumentNullException("authorizeUrl");
|
||||
}
|
||||
this.authorizeUrl = authorizeUrl;
|
||||
|
||||
if (accessTokenUrl == null)
|
||||
{
|
||||
throw new ArgumentNullException("accessTokenUrl");
|
||||
}
|
||||
this.accessTokenUrl = accessTokenUrl;
|
||||
|
||||
if (redirectUrl == null)
|
||||
throw new Exception("redirectUrl is null");
|
||||
|
||||
this.redirectUrl = redirectUrl;
|
||||
|
||||
this.getUsernameAsync = getUsernameAsync;
|
||||
}
|
||||
|
||||
|
||||
OAuthenticator(Uri redirectUrl, string clientSecret = null, Uri accessTokenUrl = null)
|
||||
|
||||
{
|
||||
this.redirectUrl = redirectUrl;
|
||||
|
||||
this.clientSecret = clientSecret;
|
||||
|
||||
this.accessTokenUrl = accessTokenUrl;
|
||||
|
||||
//
|
||||
// Generate a unique state string to check for forgeries
|
||||
//
|
||||
var chars = new char[16];
|
||||
var rand = new Random();
|
||||
for (var i = 0; i < chars.Length; i++)
|
||||
{
|
||||
chars[i] = (char)rand.Next((int)'a', (int)'z' + 1);
|
||||
}
|
||||
this.requestState = new string(chars);
|
||||
}
|
||||
|
||||
bool IsImplicit { get { return accessTokenUrl == null; } }
|
||||
|
||||
/// <summary>
|
||||
/// Method that returns the initial URL to be displayed in the web browser.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A task that will return the initial URL.
|
||||
/// </returns>
|
||||
public Task<Uri> GetInitialUrlAsync()
|
||||
{
|
||||
var url = new Uri(string.Format(
|
||||
"{0}?client_id={1}&redirect_uri={2}&response_type={3}&scope={4}&state={5}",
|
||||
authorizeUrl.AbsoluteUri,
|
||||
Uri.EscapeDataString(clientId),
|
||||
Uri.EscapeDataString(RedirectUrl.AbsoluteUri),
|
||||
IsImplicit ? "token" : "code",
|
||||
Uri.EscapeDataString(scope),
|
||||
Uri.EscapeDataString(requestState)));
|
||||
|
||||
var tcs = new TaskCompletionSource<Uri>();
|
||||
tcs.SetResult(url);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a new page has been loaded.
|
||||
/// </summary>
|
||||
/// <param name='url'>
|
||||
/// URL of the page.
|
||||
/// </param>
|
||||
/// <param name='query'>
|
||||
/// The parsed query of the URL.
|
||||
/// </param>
|
||||
/// <param name='fragment'>
|
||||
/// The parsed fragment of the URL.
|
||||
/// </param>
|
||||
protected void OnPageEncountered(Uri url, IDictionary<string, string> query, IDictionary<string, string> fragment)
|
||||
{
|
||||
|
||||
if (url.AbsoluteUri.StartsWith(this.redirectUrl.AbsoluteUri))
|
||||
{
|
||||
if (!this.redirectUrl.Equals(url)) {
|
||||
|
||||
// this is not our redirect page,
|
||||
// but perhaps one one the third party identity providers
|
||||
// One don't check for a state here.
|
||||
//
|
||||
if (fragment.ContainsKey("continue")) {
|
||||
var cont = fragment["continue"];
|
||||
// TODO continue browsing this address
|
||||
|
||||
var tcs = new TaskCompletionSource<Uri>();
|
||||
tcs.SetResult(new Uri(cont));
|
||||
tcs.Task.RunSynchronously();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var all = new Dictionary<string, string>(query);
|
||||
foreach (var kv in fragment)
|
||||
all[kv.Key] = kv.Value;
|
||||
|
||||
//
|
||||
// Check for forgeries
|
||||
//
|
||||
if (all.ContainsKey("state"))
|
||||
{
|
||||
if (all["state"] != requestState && !reportedForgery)
|
||||
{
|
||||
reportedForgery = true;
|
||||
OnError("Invalid state from server. Possible forgery!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnError(string v)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private void OnError(AggregateException ex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
/// Raised when a new page has been loaded.
|
||||
/// </summary>
|
||||
/// <param name='url'>
|
||||
/// URL of the page.
|
||||
/// </param>
|
||||
/// <param name='query'>
|
||||
/// The parsed query string of the URL.
|
||||
/// </param>
|
||||
/// <param name='fragment'>
|
||||
/// The parsed fragment of the URL.
|
||||
/// </param>
|
||||
protected void OnRedirectPageLoaded(Uri url, IDictionary<string, string> query, IDictionary<string, string> fragment)
|
||||
{
|
||||
//
|
||||
// Look for the access_token
|
||||
//
|
||||
if (fragment.ContainsKey("access_token"))
|
||||
{
|
||||
//
|
||||
// We found an access_token
|
||||
//
|
||||
OnRetrievedAccountProperties(fragment);
|
||||
}
|
||||
else if (!IsImplicit)
|
||||
{
|
||||
//
|
||||
// Look for the code
|
||||
//
|
||||
if (query.ContainsKey("code"))
|
||||
{
|
||||
var code = query["code"];
|
||||
RequestAccessTokenAsync(code).ContinueWith(task =>
|
||||
{
|
||||
if (task.IsFaulted)
|
||||
{
|
||||
OnError(task.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnRetrievedAccountProperties(task.Result);
|
||||
}
|
||||
}, TaskScheduler.FromCurrentSynchronizationContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
OnError("Expected code in response, but did not receive one.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnError("Expected access_token in response, but did not receive one.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously requests an access token with an authorization <paramref name="code"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A dictionary of data returned from the authorization request.
|
||||
/// </returns>
|
||||
/// <param name='code'>The authorization code.</param>
|
||||
/// <remarks>Implements: http://tools.ietf.org/html/rfc6749#section-4.1</remarks>
|
||||
Task<IDictionary<string, string>> RequestAccessTokenAsync(string code)
|
||||
{
|
||||
var queryValues = new Dictionary<string, string> {
|
||||
{ "grant_type", "authorization_code" },
|
||||
{ "code", code },
|
||||
{ "redirect_uri", RedirectUrl.AbsoluteUri },
|
||||
{ "client_id", clientId }
|
||||
};
|
||||
if (!string.IsNullOrEmpty(clientSecret))
|
||||
{
|
||||
queryValues["client_secret"] = clientSecret;
|
||||
}
|
||||
|
||||
return RequestAccessTokenAsync(queryValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously makes a request to the access token URL with the given parameters.
|
||||
/// </summary>
|
||||
/// <param name="queryValues">The parameters to make the request with.</param>
|
||||
/// <returns>The data provided in the response to the access token request.</returns>
|
||||
public async Task<IDictionary<string, string>> RequestAccessTokenAsync(IDictionary<string, string> queryValues)
|
||||
{
|
||||
StringBuilder postData = new StringBuilder();
|
||||
if (!queryValues.ContainsKey("client_id"))
|
||||
{
|
||||
postData.Append("client_id="+Uri.EscapeDataString($"{this.clientId}")+"&");
|
||||
}
|
||||
if (!queryValues.ContainsKey("client_secret"))
|
||||
{
|
||||
postData.Append("client_secret="+Uri.EscapeDataString($"{this.clientSecret}")+"&");
|
||||
}
|
||||
if (!queryValues.ContainsKey("scope"))
|
||||
{
|
||||
postData.Append("scope="+Uri.EscapeDataString($"{this.scope}")+"&");
|
||||
}
|
||||
foreach (string key in queryValues.Keys)
|
||||
{
|
||||
postData.Append($"{key}="+Uri.EscapeDataString($"{queryValues[key]}")+"&");
|
||||
}
|
||||
var req = WebRequest.Create(accessTokenUrl);
|
||||
(req as HttpWebRequest).Accept = "application/json";
|
||||
req.Method = "POST";
|
||||
var body = Encoding.UTF8.GetBytes(postData.ToString());
|
||||
req.ContentLength = body.Length;
|
||||
req.ContentType = "application/x-www-form-urlencoded";
|
||||
var s = req.GetRequestStream();
|
||||
|
||||
s.Write(body, 0, body.Length);
|
||||
|
||||
var auth = await req.GetResponseAsync();
|
||||
|
||||
var repstream = auth.GetResponseStream();
|
||||
|
||||
var respReader = new StreamReader(repstream);
|
||||
|
||||
var text = await respReader.ReadToEndAsync();
|
||||
|
||||
req.Abort();
|
||||
// Parse the response
|
||||
var data = text.Contains("{") ? JsonDecode(text) : FormDecode(text);
|
||||
|
||||
if (data.ContainsKey("error"))
|
||||
{
|
||||
OnError("Error authenticating: " + data["error"]);
|
||||
}
|
||||
else if (data.ContainsKey("access_token"))
|
||||
{
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnError("Expected access_token in access token response, but did not receive one.");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private IDictionary<string,string> FormDecode(string text)
|
||||
{
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private IDictionary<string,string> JsonDecode(string text)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<Dictionary<string,string>>(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler that is fired when an access token has been retreived.
|
||||
/// </summary>
|
||||
/// <param name='accountProperties'>
|
||||
/// The retrieved account properties
|
||||
/// </param>
|
||||
protected virtual void OnRetrievedAccountProperties(IDictionary<string, string> accountProperties)
|
||||
{
|
||||
//
|
||||
// Now we just need a username for the account
|
||||
//
|
||||
if (getUsernameAsync != null)
|
||||
{
|
||||
getUsernameAsync(accountProperties).ContinueWith(task =>
|
||||
{
|
||||
if (task.IsFaulted)
|
||||
{
|
||||
OnError(task.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnSucceeded(task.Result, accountProperties);
|
||||
}
|
||||
}, TaskScheduler.FromCurrentSynchronizationContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
OnSucceeded("", accountProperties);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSucceeded(string v, IDictionary<string, string> accountProperties)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,61 +0,0 @@
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using System.Threading.Tasks;
|
||||
using NJsonSchema;
|
||||
using System.IO;
|
||||
using cli.Model;
|
||||
using Yavsc.Abstract.IT;
|
||||
|
||||
namespace cli
|
||||
{
|
||||
|
||||
public class GenerateJsonSchema : ICommander
|
||||
{
|
||||
public CommandLineApplication Integrate(CommandLineApplication rootApp)
|
||||
{
|
||||
CommandArgument genargclass = null;
|
||||
CommandArgument genargjson = null;
|
||||
CommandOption genopthelp = null;
|
||||
var cmd = rootApp.Command("gen",
|
||||
(target) =>
|
||||
{
|
||||
target.FullName = "Generete";
|
||||
target.Description = "generates some objects ...";
|
||||
genopthelp = target.HelpOption("-? | -h | --help");
|
||||
genargclass = target.Argument(
|
||||
"class",
|
||||
"class name of generation to execute (actually, only 'jsonSchema') .",
|
||||
multipleValues: false);
|
||||
genargjson = target.Argument(
|
||||
"json",
|
||||
"Json file generated",
|
||||
multipleValues: false);
|
||||
}, false);
|
||||
cmd.OnExecute(
|
||||
() => {
|
||||
if (genargclass.Value == "jsonSchema") {
|
||||
GenerateCiBuildSettingsSchema(genargjson.Value);
|
||||
} else {
|
||||
cmd.ShowHint();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
return cmd;
|
||||
}
|
||||
public static void GenerateCiBuildSettingsSchema(string outputFileName = "pauls-ci-schema.json")
|
||||
{
|
||||
var schema = JsonSchema.FromType(typeof(CiBuildSettings));
|
||||
var schemaData = schema.ToJson();
|
||||
|
||||
FileInfo ofi = new FileInfo(outputFileName);
|
||||
var ostream = ofi.OpenWrite();
|
||||
var owritter = new StreamWriter(ostream);
|
||||
owritter.WriteLine(schemaData);
|
||||
owritter.Close();
|
||||
ostream.Close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="MonthlySubjectTemplate"><value>[{0} Monthly] {1}</value></data>
|
||||
|
||||
</root>
|
||||
@ -1,253 +0,0 @@
|
||||
|
||||
using Yavsc;
|
||||
using cli.Services;
|
||||
using cli.Settings;
|
||||
using System.Runtime.Versioning;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace cli
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public string ConnectionString
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public static ConnectionSettings ConnectionSettings { get; set; }
|
||||
|
||||
public static UserConnectionSettings UserConnectionSettings { get; set; }
|
||||
|
||||
|
||||
|
||||
public static string HostingFullName { get; private set; }
|
||||
|
||||
|
||||
public static string EnvironmentName { get; private set; }
|
||||
public static Microsoft.Extensions.Logging.ILogger Logger { get; private set; }
|
||||
public Startup()
|
||||
{
|
||||
var devtag = env.IsDevelopment() ? "D" : "";
|
||||
var prodtag = env.IsProduction() ? "P" : "";
|
||||
var stagetag = env.IsStaging() ? "S" : "";
|
||||
EnvironmentName = env.EnvironmentName;
|
||||
|
||||
HostingFullName = $"{appEnv.RuntimeFramework.FullName} [{env.EnvironmentName}:{prodtag}{devtag}{stagetag}]";
|
||||
|
||||
// Set up configuration sources.
|
||||
UserConnectionsettingsFileName = $"connectionsettings.{env.EnvironmentName}.json";
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||
.AddJsonFile(UserConnectionsettingsFileName, optional: true);
|
||||
|
||||
Configuration = builder.Build();
|
||||
ConnectionString = Configuration["ConnectionStrings:Default"];
|
||||
}
|
||||
|
||||
public static void SaveCredentials(string fileName, bool condensed=false) {
|
||||
var cf = new FileInfo(fileName);
|
||||
using (var writer = cf.OpenWrite())
|
||||
{
|
||||
using (var textWriter = new StreamWriter(writer))
|
||||
{
|
||||
var data = new { UserConnection = UserConnectionSettings, Connection = ConnectionSettings };
|
||||
var json = JsonConvert.SerializeObject(data, condensed ? Formatting.None : Formatting.Indented);
|
||||
textWriter.Write(json);
|
||||
textWriter.Close();
|
||||
}
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static string UserConnectionsettingsFileName { get ; private set;}
|
||||
|
||||
const string userCxKey = "UserConnection";
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddOptions();
|
||||
var cxSettings = Configuration.GetSection("Connection");
|
||||
services.Configure<ConnectionSettings>(cxSettings);
|
||||
var cxUserSettings = Configuration.GetSection(userCxKey);
|
||||
services.Configure<UserConnectionSettings>(cxUserSettings);
|
||||
|
||||
var smtpSettingsconf = Configuration.GetSection("Smtp");
|
||||
// TODO give it a look : Microsoft.Extensions.CodeGenerators.Mvc.View.ViewGeneratorTemplateModel v;
|
||||
|
||||
services.Configure<SmtpSettings>(smtpSettingsconf);
|
||||
services.Configure<GenMvcSettings>(Configuration.GetSection("gen_mvc"));
|
||||
services.AddInstance(typeof(ILoggerFactory), new LoggerFactory());
|
||||
services.AddTransient(typeof(IEmailSender), typeof(MailSender));
|
||||
services.AddTransient(typeof(RazorEngineHost),
|
||||
svs => {
|
||||
var settings = svs.GetService<GenMvcSettings>();
|
||||
|
||||
return new YaRazorEngineHost {
|
||||
DefaultBaseClass = "Microsoft.Extensions.CodeGenerators.Mvc.View.ViewGeneratorTemplateModel",
|
||||
DefaultClassName = settings.ControllerName,
|
||||
DefaultNamespace = settings.NameSpace }; }
|
||||
);
|
||||
// Well ... I'll perhaps have, one day, enough trust to use it ...
|
||||
services.AddTransient(typeof(MvcGenerator), typeof(MvcGenerator));
|
||||
services.AddEntityFramework().AddNpgsql().AddDbContext<ApplicationDbContext>(
|
||||
db => db.UseNpgsql(ConnectionString)
|
||||
);
|
||||
|
||||
services.AddTransient((s) => new RazorTemplateEngine(s.GetService<RazorEngineHost>()));
|
||||
services.AddTransient(typeof(IModelTypesLocator), typeof(ModelTypesLocator));
|
||||
services.AddTransient(typeof(ILibraryExporter), typeof(RuntimeLibraryExporter));
|
||||
services.AddLogging();
|
||||
services.AddTransient<EMailer>();
|
||||
services.AddLocalization(options =>
|
||||
{
|
||||
options.ResourcesPath = "Resources";
|
||||
});
|
||||
services.Configure<SharedAuthenticationOptions>(options =>
|
||||
{
|
||||
options.SignInScheme = "Bearer";
|
||||
});
|
||||
|
||||
services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>();
|
||||
|
||||
services.AddAuthentication("Bearer");
|
||||
|
||||
services.AddSingleton(typeof(IApplicationEnvironment), svs => PlatformServices.Default.Application);
|
||||
services.AddSingleton(typeof(IRuntimeEnvironment), svs => PlatformServices.Default.Runtime);
|
||||
services.AddSingleton(typeof(IAssemblyLoadContextAccessor), svs => PlatformServices.Default.AssemblyLoadContextAccessor);
|
||||
services.AddSingleton(typeof(IAssemblyLoaderContainer), svs => PlatformServices.Default.AssemblyLoaderContainer);
|
||||
services.AddSingleton(typeof(ILibraryManager), svs => PlatformServices.Default.LibraryManager);
|
||||
services.AddSingleton<UserManager<ApplicationDbContext>>();
|
||||
|
||||
services.AddSingleton(typeof(BootstrapperContext),
|
||||
svs => new BootstrapperContext
|
||||
{
|
||||
RuntimeDirectory = Path.GetDirectoryName(typeof(BootstrapperContext).Assembly.Location),
|
||||
ApplicationBase = Configuration["gen_mvc:AppBase"],
|
||||
// NOTE(anurse): Mono is always "dnx451" (for now).
|
||||
TargetFramework = new FrameworkName("DNX", new Version(4, 5, 1)),
|
||||
RuntimeType = "Mono"
|
||||
}
|
||||
);
|
||||
|
||||
services.AddTransient(typeof(CompilationEngine),
|
||||
svs => {
|
||||
var logger = svs.GetService<ILoggerFactory>().CreateLogger<Startup>();
|
||||
var project = svs.GetService<Project>();
|
||||
var env = new ApplicationEnvironment(project,
|
||||
PlatformServices.Default.Application.RuntimeFramework,
|
||||
PlatformServices.Default.Application.Configuration,
|
||||
PlatformServices.Default.Application
|
||||
);
|
||||
logger.LogInformation("app name: "+env.ApplicationName);
|
||||
|
||||
return new CompilationEngine(
|
||||
new CompilationEngineContext(PlatformServices.Default.Application,
|
||||
PlatformServices.Default.Runtime,
|
||||
PlatformServices.Default.AssemblyLoadContextAccessor.Default, new CompilationCache()));
|
||||
});
|
||||
|
||||
services.AddTransient(typeof(IFrameworkReferenceResolver),
|
||||
svs => new FrameworkReferenceResolver());
|
||||
|
||||
services.AddTransient(
|
||||
typeof(Project), svs =>
|
||||
{
|
||||
Project project = null;
|
||||
var diag = new List<DiagnosticMessage>();
|
||||
var settings = svs.GetService<IOptions<GenMvcSettings>>();
|
||||
if (Project.TryGetProject(settings.Value.AppBase, out project, diag))
|
||||
{
|
||||
return project;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
services.AddTransient(
|
||||
typeof(ILibraryExporter),
|
||||
svs =>
|
||||
{
|
||||
var settings = svs.GetService<IOptions<GenMvcSettings>>();
|
||||
var compilationEngine = svs.GetService<CompilationEngine>();
|
||||
var bootstrappercontext = svs.GetService<BootstrapperContext>();
|
||||
var project = svs.GetService<Project>();
|
||||
if (settings == null)
|
||||
throw new Exception("settings are missing to generate some server code (GenMvcSettings) ");
|
||||
|
||||
return
|
||||
new RuntimeLibraryExporter(
|
||||
() => compilationEngine.CreateProjectExporter
|
||||
(project, bootstrappercontext.TargetFramework, settings.Value.ConfigurationName));
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
services.AddTransient(typeof(IEntityFrameworkService), typeof(EntityFrameworkServices));
|
||||
services.AddTransient(typeof(IDbContextEditorServices), typeof(DbContextEditorServices));
|
||||
services.AddTransient(typeof(IFilesLocator), typeof(FilesLocator));
|
||||
services.AddTransient(typeof(
|
||||
Microsoft.Extensions.CodeGeneration.Templating.ITemplating), typeof(
|
||||
Microsoft.Extensions.CodeGeneration.Templating.RazorTemplating));
|
||||
services.AddTransient(
|
||||
typeof(Microsoft.Extensions.CodeGeneration.Templating.Compilation.ICompilationService),
|
||||
typeof(Microsoft.Extensions.CodeGeneration.Templating.Compilation.RoslynCompilationService));
|
||||
|
||||
services.AddTransient(
|
||||
typeof(
|
||||
Microsoft.Extensions.CodeGeneration.ICodeGeneratorActionsService),
|
||||
typeof(Microsoft.Extensions.CodeGeneration.CodeGeneratorActionsService));
|
||||
|
||||
|
||||
services.AddTransient(typeof(Microsoft.Dnx.Compilation.ICompilerOptionsProvider),
|
||||
svs =>
|
||||
{
|
||||
var bsContext = svs.GetService<BootstrapperContext>();
|
||||
var compileEngine = svs.GetService<ICompilationEngine>();
|
||||
|
||||
var applicationHostContext = new ApplicationHostContext
|
||||
{
|
||||
ProjectDirectory = bsContext.ApplicationBase,
|
||||
RuntimeIdentifiers = new string[] { "dnx451" },
|
||||
TargetFramework = bsContext.TargetFramework
|
||||
};
|
||||
|
||||
var libraries = ApplicationHostContext.GetRuntimeLibraries(applicationHostContext, throwOnInvalidLockFile: true);
|
||||
var projects = libraries.Where(p => p.Type == LibraryTypes.Project)
|
||||
.ToDictionary(p => p.Identity.Name, p => (ProjectDescription)p);
|
||||
Logger.LogInformation($"Found {projects?.Count} projects");
|
||||
return new CompilerOptionsProvider(projects);
|
||||
});
|
||||
services.AddMvc();
|
||||
services.AddTransient(typeof(IPackageInstaller),typeof(PackageInstaller));
|
||||
services.AddTransient(typeof(Microsoft.Extensions.CodeGeneration.ILogger),typeof(Microsoft.Extensions.CodeGeneration.ConsoleLogger));
|
||||
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>(
|
||||
option =>
|
||||
{
|
||||
option.User.RequireUniqueEmail = true;
|
||||
option.SignIn.RequireConfirmedAccount = true;
|
||||
}
|
||||
).AddEntityFrameworkStores<ApplicationDbContext>();
|
||||
Services = services;
|
||||
}
|
||||
|
||||
public void Configure(
|
||||
IOptions<ConnectionSettings> cxSettings,
|
||||
IOptions<UserConnectionSettings> useCxSettings,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
loggerFactory.AddDebug();
|
||||
Logger = loggerFactory.CreateLogger<Startup>();
|
||||
var authConf = Configuration.GetSection("Authentication").GetSection("Yavsc");
|
||||
var clientId = authConf.GetSection("ClientId").Value;
|
||||
var clientSecret = authConf.GetSection("ClientSecret").Value;
|
||||
ConnectionSettings = cxSettings?.Value ?? new ConnectionSettings();
|
||||
UserConnectionSettings = useCxSettings?.Value ?? new UserConnectionSettings();
|
||||
Logger.LogInformation($"Configuration ended, with hosting Full Name: {HostingFullName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
|
||||
namespace SeleniumDocs.GettingStarted;
|
||||
|
||||
public static class FirstScript
|
||||
{
|
||||
public static void DoTestSeleniumWebSite()
|
||||
{
|
||||
IWebDriver driver = new ChromeDriver();
|
||||
|
||||
driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
|
||||
|
||||
var title = driver.Title;
|
||||
|
||||
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
|
||||
|
||||
var textBox = driver.FindElement(By.Name("my-text"));
|
||||
var submitButton = driver.FindElement(By.TagName("button"));
|
||||
|
||||
textBox.SendKeys("Selenium");
|
||||
submitButton.Click();
|
||||
|
||||
var message = driver.FindElement(By.Id("message"));
|
||||
var value = message.Text;
|
||||
|
||||
driver.Quit();
|
||||
}
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace yavscTests
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Since node isn't any requirement by here,
|
||||
/// It may regress
|
||||
/// </summary>
|
||||
[Trait("regression", "allways")]
|
||||
public class NodeTests
|
||||
{
|
||||
void TestNodeJsForAnsitohtml ()
|
||||
{
|
||||
var procStart = new ProcessStartInfo("node", "node_modules/ansi-to-html/bin/ansi-to-html")
|
||||
{
|
||||
UseShellExecute = false,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true
|
||||
};
|
||||
var proc = Process.Start(procStart);
|
||||
proc.StandardInput.WriteLine("\x001b[30mblack\x1b[37mwhite");
|
||||
proc.StandardInput.Close();
|
||||
while (!proc.StandardOutput.EndOfStream)
|
||||
{
|
||||
Console.Write(proc.StandardOutput.ReadToEnd());
|
||||
}
|
||||
}
|
||||
|
||||
void AnsiToHtml()
|
||||
{
|
||||
var procStart = new ProcessStartInfo("ls", "-l --color=always")
|
||||
{
|
||||
UseShellExecute = false,
|
||||
RedirectStandardInput = false,
|
||||
RedirectStandardOutput = true
|
||||
};
|
||||
var proc = Process.Start(procStart);
|
||||
var encoded = GetStream(proc.StandardOutput);
|
||||
var reader = new StreamReader(encoded);
|
||||
var txt = reader.ReadToEnd();
|
||||
|
||||
Console.WriteLine(txt);
|
||||
}
|
||||
|
||||
public static Stream GetStream(StreamReader reader)
|
||||
{
|
||||
var procStart = new ProcessStartInfo("node", "node_modules/ansi-to-html/bin/ansi-to-html");
|
||||
procStart.UseShellExecute = false;
|
||||
procStart.RedirectStandardInput = true;
|
||||
procStart.RedirectStandardOutput = true;
|
||||
procStart.RedirectStandardError = true;
|
||||
var mem = new MemoryStream();
|
||||
StreamWriter writer = new StreamWriter(mem);
|
||||
var proc = Process.Start(procStart);
|
||||
var text = reader.ReadToEnd();
|
||||
proc.StandardInput.WriteLine(text);
|
||||
proc.StandardInput.Close();
|
||||
return proc.StandardOutput.BaseStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue