From 9e4860b2335f41299809cb0dcbb61ccf2f188f98 Mon Sep 17 00:00:00 2001 From: Jochen Wezel Date: Thu, 29 Oct 2020 09:09:48 +0100 Subject: [PATCH 1/2] For #1 added some required classes for client initialization, first compilable version --- CenterDevice.Rest/CenterDevice.Rest.csproj | 5 + CenterDevice.Rest/IO/CenterDeviceIOClient.cs | 4 + .../Rest/Clients/CenterDeviceClient.cs | 78 ++- .../Rest/Clients/CenterDeviceClientBase.cs | 40 +- .../Rest/Clients/CenterDeviceConfiguration.cs | 472 ++++++++++++++++++ .../Rest/Clients/CenterDeviceErrorHandler.cs | 59 +++ .../Clients/CenterDeviceOAuthInfoProvider.cs | 38 ++ .../Clients/Collections/CollectionsResults.cs | 2 +- .../Rest/Clients/DiagnosticTools.cs | 6 +- .../Rest/Clients/Folders/Folder.cs | 2 +- .../Rest/Clients/OAuth/OAuthInfo.cs | 14 + .../OAuth/OAuthTokenEndpointConfiguration.cs | 42 ++ .../Rest/Clients/RestClientConfiguration.cs | 31 ++ CenterDevice.SampleApp/Program.cs | 30 +- 14 files changed, 784 insertions(+), 39 deletions(-) create mode 100644 CenterDevice.Rest/Rest/Clients/CenterDeviceConfiguration.cs create mode 100644 CenterDevice.Rest/Rest/Clients/CenterDeviceErrorHandler.cs create mode 100644 CenterDevice.Rest/Rest/Clients/CenterDeviceOAuthInfoProvider.cs create mode 100644 CenterDevice.Rest/Rest/Clients/OAuth/OAuthTokenEndpointConfiguration.cs create mode 100644 CenterDevice.Rest/Rest/Clients/RestClientConfiguration.cs diff --git a/CenterDevice.Rest/CenterDevice.Rest.csproj b/CenterDevice.Rest/CenterDevice.Rest.csproj index e9e23b4..3f8aa3d 100644 --- a/CenterDevice.Rest/CenterDevice.Rest.csproj +++ b/CenterDevice.Rest/CenterDevice.Rest.csproj @@ -112,6 +112,9 @@ + + + @@ -148,6 +151,8 @@ + + diff --git a/CenterDevice.Rest/IO/CenterDeviceIOClient.cs b/CenterDevice.Rest/IO/CenterDeviceIOClient.cs index 97a308b..ca5ae2c 100644 --- a/CenterDevice.Rest/IO/CenterDeviceIOClient.cs +++ b/CenterDevice.Rest/IO/CenterDeviceIOClient.cs @@ -4,6 +4,10 @@ namespace CenterDevice.IO { public class CenterDeviceIOClient : IOClientBase { + public CenterDeviceIOClient(CenterDevice.Rest.Clients.CenterDeviceClient centerDeviceClient) : this(centerDeviceClient, centerDeviceClient.Token.UserId) + { + } + public CenterDeviceIOClient(CenterDevice.Rest.Clients.CenterDeviceClient centerDeviceClient, string userID) : base(centerDeviceClient, userID) { this.centerDeviceClient = centerDeviceClient; diff --git a/CenterDevice.Rest/Rest/Clients/CenterDeviceClient.cs b/CenterDevice.Rest/Rest/Clients/CenterDeviceClient.cs index d77e755..78dfabc 100644 --- a/CenterDevice.Rest/Rest/Clients/CenterDeviceClient.cs +++ b/CenterDevice.Rest/Rest/Clients/CenterDeviceClient.cs @@ -14,12 +14,84 @@ namespace CenterDevice.Rest.Clients /// public class CenterDeviceClient : CenterDeviceClientBase { - public CenterDeviceClient(IOAuthInfoProvider oAuthInfoProvider, IRestClientConfiguration configuration, IRestClientErrorHandler errorHandler) : base(oAuthInfoProvider, configuration, errorHandler, "v2/") + public CenterDeviceClient() : this(null, CenterDevice.Rest.Clients.CenterDeviceConfiguration.Default) { } - public Rest.Clients.HealthCheck.HealthCheckRestClient HealthCheck => new Rest.Clients.HealthCheck.HealthCheckRestClient(configuration, errorHandler); + public CenterDeviceClient(IOAuthInfoProvider oAuthInfoProvider, CenterDevice.Rest.Clients.CenterDeviceConfiguration configuration) : this(oAuthInfoProvider, configuration.OAuthConfiguration()) + { + this.Config = configuration; + } + + private CenterDeviceClient(IOAuthInfoProvider oAuthInfoProvider, IRestClientConfiguration configuration) : this(oAuthInfoProvider, configuration, new CenterDevice.Rest.Clients.CenterDeviceErrorHandler(null, oAuthInfoProvider)) + { + } + + private CenterDeviceClient(IOAuthInfoProvider oAuthInfoProvider, IRestClientConfiguration configuration, IRestClientErrorHandler errorHandler) : base(oAuthInfoProvider, configuration, errorHandler, "v2/") + { + } + + public CenterDevice.Rest.Clients.HealthCheck.HealthCheckRestClient HealthCheck => new CenterDevice.Rest.Clients.HealthCheck.HealthCheckRestClient(configuration, errorHandler); + + protected override string UploadLinkBaseUrl => this.Config.UploadLinkBaseUrl; + + /// + /// Configuration for accessing CenterDevice API + /// + public CenterDevice.Rest.Clients.CenterDeviceConfiguration Config { get; set; } + + /// + /// Client token for accessing CenterDevice API + /// + public CenterDevice.Rest.Clients.OAuth.OAuthInfo Token { get; set; } - protected override string UploadLinkBaseUrl => "https://upload.centerdevice.de/"; + /// + /// Authorize user with username, customer number, organisation name and password as set up in configuration + /// + public void AuthorizeWithToken(CenterDevice.Rest.Clients.OAuth.OAuthInfo token) + { + this.Token = token; + } + + /// + /// Authorize user with username, customer number, organisation name and password as set up in configuration + /// + public void AuthorizeWithUserCredentials() + { + //this.Token = this.AuthorizationApi.TokenWithHttpInfo("password", this.Config.ClientNumber, null, null, this.Config.Username, null, this.Config.OrganisationName, this.Config.Password, null, null, null, null).Data; + //this.Token = this.AuthorizationApi.TokenWithHttpInfo("password", null, null, null, this.Config.Username, null, null, this.Config.Password, null, null, null, null).Data; + } + + /// + /// Update configuration and authorize user + /// + /// + /// + /// + public void AuthorizeWithUserCredentials(string username, string password) + //public void AuthorizeWithUserCredentials(string username, string customerNo, string password) + { + this.Config.Username = username; + //this.Config.ClientNumber = customerNo; + this.Config.Password = password; + this.AuthorizeWithUserCredentials(); + } + + /// + /// Update configuration and authorize user + /// + /// + /// + /// + /// + public void AuthorizeWithUserCredentials(string username, string organisationName, string password) + //public void AuthorizeWithUserCredentials(string username, string customerNo, string organisationName, string password) + { + this.Config.Username = username; + //this.Config.ClientNumber = customerNo; + //this.Config.OrganisationName = organisationName; + this.Config.Password = password; + this.AuthorizeWithUserCredentials(); + } } } diff --git a/CenterDevice.Rest/Rest/Clients/CenterDeviceClientBase.cs b/CenterDevice.Rest/Rest/Clients/CenterDeviceClientBase.cs index f4614ca..8c1ba9a 100644 --- a/CenterDevice.Rest/Rest/Clients/CenterDeviceClientBase.cs +++ b/CenterDevice.Rest/Rest/Clients/CenterDeviceClientBase.cs @@ -44,25 +44,25 @@ public virtual IStreamWrapper DefaultStreamWrapper() protected abstract string UploadLinkBaseUrl { get; } - public Rest.Clients.Folders.FolderRestClient Folder => new Rest.Clients.Folders.FolderRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Folders.FoldersRestClient Folders => new Rest.Clients.Folders.FoldersRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Collections.CollectionRestClient Collection => new Rest.Clients.Collections.CollectionRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Collections.CollectionsRestClient Collections => new Rest.Clients.Collections.CollectionsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Documents.DocumentsRestClient Documents => new Rest.Clients.Documents.DocumentsRestClient(oAuthInfoProvider, configuration, errorHandler, this.DefaultStreamWrapper(), apiVersionPrefix); - public Rest.Clients.Documents.DocumentRestClient Document => new Rest.Clients.Documents.DocumentRestClient(oAuthInfoProvider, configuration, errorHandler, this.DefaultStreamWrapper(), apiVersionPrefix); - public Rest.Clients.Groups.GroupRestClient Group => new Rest.Clients.Groups.GroupRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Groups.GroupsRestClient Groups => new Rest.Clients.Groups.GroupsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Link.LinkRestClient Link => new Rest.Clients.Link.LinkRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Link.LinksRestClient Links => new Rest.Clients.Link.LinksRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Link.UploadLinkRestClient UploadLink => new Rest.Clients.Link.UploadLinkRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix, UploadLinkBaseUrl); - public Rest.Clients.Link.UploadLinksRestClient UploadLinks => new Rest.Clients.Link.UploadLinksRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix, UploadLinkBaseUrl); - public Rest.Clients.User.UserRestClient User => new Rest.Clients.User.UserRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.User.UsersRestClient Users => new Rest.Clients.User.UsersRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.User.UserSettingsRestClient UserSettings => new Rest.Clients.User.UserSettingsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Timeline.TimelineRestClient Timeline => new Rest.Clients.Timeline.TimelineRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Tenant.TenantFeaturesRestClient TenantFeatures => new Rest.Clients.Tenant.TenantFeaturesRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Tenant.TenantRestClient Tenant => new Rest.Clients.Tenant.TenantRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Tenant.TenantSettingsRestClient TenantSettings => new Rest.Clients.Tenant.TenantSettingsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); - public Rest.Clients.Tenant.TenantsRestClient Tenants => new Rest.Clients.Tenant.TenantsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Folders.FolderRestClient Folder => new CenterDevice.Rest.Clients.Folders.FolderRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Folders.FoldersRestClient Folders => new CenterDevice.Rest.Clients.Folders.FoldersRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Collections.CollectionRestClient Collection => new CenterDevice.Rest.Clients.Collections.CollectionRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Collections.CollectionsRestClient Collections => new CenterDevice.Rest.Clients.Collections.CollectionsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Documents.DocumentsRestClient Documents => new CenterDevice.Rest.Clients.Documents.DocumentsRestClient(oAuthInfoProvider, configuration, errorHandler, this.DefaultStreamWrapper(), apiVersionPrefix); + public CenterDevice.Rest.Clients.Documents.DocumentRestClient Document => new CenterDevice.Rest.Clients.Documents.DocumentRestClient(oAuthInfoProvider, configuration, errorHandler, this.DefaultStreamWrapper(), apiVersionPrefix); + public CenterDevice.Rest.Clients.Groups.GroupRestClient Group => new CenterDevice.Rest.Clients.Groups.GroupRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Groups.GroupsRestClient Groups => new CenterDevice.Rest.Clients.Groups.GroupsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Link.LinkRestClient Link => new CenterDevice.Rest.Clients.Link.LinkRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Link.LinksRestClient Links => new CenterDevice.Rest.Clients.Link.LinksRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Link.UploadLinkRestClient UploadLink => new CenterDevice.Rest.Clients.Link.UploadLinkRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix, UploadLinkBaseUrl); + public CenterDevice.Rest.Clients.Link.UploadLinksRestClient UploadLinks => new CenterDevice.Rest.Clients.Link.UploadLinksRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix, UploadLinkBaseUrl); + public CenterDevice.Rest.Clients.User.UserRestClient User => new CenterDevice.Rest.Clients.User.UserRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.User.UsersRestClient Users => new CenterDevice.Rest.Clients.User.UsersRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.User.UserSettingsRestClient UserSettings => new CenterDevice.Rest.Clients.User.UserSettingsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Timeline.TimelineRestClient Timeline => new CenterDevice.Rest.Clients.Timeline.TimelineRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Tenant.TenantFeaturesRestClient TenantFeatures => new CenterDevice.Rest.Clients.Tenant.TenantFeaturesRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Tenant.TenantRestClient Tenant => new CenterDevice.Rest.Clients.Tenant.TenantRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Tenant.TenantSettingsRestClient TenantSettings => new CenterDevice.Rest.Clients.Tenant.TenantSettingsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); + public CenterDevice.Rest.Clients.Tenant.TenantsRestClient Tenants => new CenterDevice.Rest.Clients.Tenant.TenantsRestClient(oAuthInfoProvider, configuration, errorHandler, apiVersionPrefix); } } diff --git a/CenterDevice.Rest/Rest/Clients/CenterDeviceConfiguration.cs b/CenterDevice.Rest/Rest/Clients/CenterDeviceConfiguration.cs new file mode 100644 index 0000000..6a7ad51 --- /dev/null +++ b/CenterDevice.Rest/Rest/Clients/CenterDeviceConfiguration.cs @@ -0,0 +1,472 @@ +using System; +using System.Reflection; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace CenterDevice.Rest.Clients +{ + /// + /// Represents a set of configuration settings + /// + public class CenterDeviceConfiguration + { + #region Constants + + /// + /// Version of the package. + /// + /// Version of the package. + public const string Version = "1.0.0"; + + /// + /// Identifier for ISO 8601 DateTime Format + /// + /// See https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 for more information. + // ReSharper disable once InconsistentNaming + public const string ISO8601_DATETIME_FORMAT = "o"; + + #endregion Constants + + #region Static Members + + private static readonly object GlobalConfigSync = new { }; + private static CenterDeviceConfiguration _globalConfiguration; + + ///// + ///// Default creation of exceptions for a given method name and response object + ///// + //public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) => + //{ + // var status = (int)response.StatusCode; + // if (status >= 400) + // { + // return new ApiException(status, + // string.Format("Error calling {0}: {1}", methodName, response.Content), + // response.Content); + // } + // if (status == 0) + // { + // return new ApiException(status, + // string.Format("Error calling {0}: {1}", methodName, response.ErrorMessage), response.ErrorMessage); + // } + // return null; + //}; + + /// + /// Gets or sets the default Configuration. + /// + /// Configuration. + public static CenterDeviceConfiguration Default + { + get { return _globalConfiguration; } + set + { + lock (GlobalConfigSync) + { + _globalConfiguration = value; + } + } + } + + #endregion Static Members + + #region Private Members + + /// + /// Gets or sets the API key based on the authentication name. + /// + /// The API key. + private IDictionary _apiKey = null; + + /// + /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name. + /// + /// The prefix of the API key. + private IDictionary _apiKeyPrefix = null; + + private string _dateTimeFormat = ISO8601_DATETIME_FORMAT; + private string _tempFolderPath = Path.GetTempPath(); + + #endregion Private Members + + #region Constructors + + static CenterDeviceConfiguration() + { + _globalConfiguration = new CenterDeviceConfiguration(); + } + + /// + /// Initializes a new instance of the class + /// + public CenterDeviceConfiguration() + { + UserAgent = "CompuMaster CenterDevice/0.1.0/.Net"; + BasePath = "https://auth.centerdevice.de/token"; + DefaultHeader = new ConcurrentDictionary(); + ApiKey = new ConcurrentDictionary(); + ApiKeyPrefix = new ConcurrentDictionary(); + + // Setting Timeout has side effects (forces ApiClient creation). + Timeout = 100000; + } + + /// + /// Initializes a new instance of the class + /// + public CenterDeviceConfiguration( + IDictionary defaultHeader, + IDictionary apiKey, + IDictionary apiKeyPrefix, + string basePath = "https://auth.centerdevice.de/token") : this() + { + if (string.IsNullOrWhiteSpace(basePath)) + throw new ArgumentException("The provided basePath is invalid.", "basePath"); + if (defaultHeader == null) + throw new ArgumentNullException("defaultHeader"); + if (apiKey == null) + throw new ArgumentNullException("apiKey"); + if (apiKeyPrefix == null) + throw new ArgumentNullException("apiKeyPrefix"); + + BasePath = basePath; + + foreach (var keyValuePair in defaultHeader) + { + DefaultHeader.Add(keyValuePair); + } + + foreach (var keyValuePair in apiKey) + { + ApiKey.Add(keyValuePair); + } + + foreach (var keyValuePair in apiKeyPrefix) + { + ApiKeyPrefix.Add(keyValuePair); + } + } + + ///// + ///// Initializes a new instance of the class with different settings + ///// + ///// Api client + ///// Dictionary of default HTTP header + ///// Username + ///// Password + ///// accessToken + ///// Dictionary of API key + ///// Dictionary of API key prefix + ///// Temp folder path + ///// DateTime format string + ///// HTTP connection timeout (in milliseconds) + ///// HTTP user agent + //[Obsolete("Use explicit object construction and setting of properties.", true)] + //internal CenterDeviceConfiguration( + // // ReSharper disable UnusedParameter.Local + // ApiClient apiClient = null, + // IDictionary defaultHeader = null, + // string username = null, + // string password = null, + // string accessToken = null, + // IDictionary apiKey = null, + // IDictionary apiKeyPrefix = null, + // string tempFolderPath = null, + // string dateTimeFormat = null, + // int timeout = 100000, + // string userAgent = "CompuMaster CenterDevice/0.1.0/.Net" + // // ReSharper restore UnusedParameter.Local + // ) + //{ + + //} + + ///// + ///// Initializes a new instance of the Configuration class. + ///// + ///// Api client. + //[Obsolete("This constructor caused unexpected sharing of static data. It is no longer supported.", true)] + //// ReSharper disable once UnusedParameter.Local + //internal CenterDeviceConfiguration(ApiClient apiClient) + //{ + + //} + + #endregion Constructors + + + #region Properties + + private CenterDevice.Rest.Clients.CenterDeviceClient _apiClient = null; + /// + /// Gets an instance of an ApiClient for this configuration + /// + internal virtual CenterDevice.Rest.Clients.CenterDeviceClient ApiClient + { + get + { + if (_apiClient == null) _apiClient = CreateApiClient(); + return _apiClient; + } + } + + private String _basePath = null; + /// + /// Gets or sets the base path for API access. + /// + public virtual string BasePath + { + get { return _basePath; } + set + { + _basePath = value; + //// pass-through to ApiClient if it's set. + //if (_apiClient != null) + //{ + // _apiClient.RestClient.BaseUrl = new Uri(_basePath); + //} + } + } + + private String _uploadLinkBaseUrl = "https://upload.centerdevice.de/"; + /// + /// Gets or sets the base address for upload urls + /// + public virtual String UploadLinkBaseUrl + { + get { return this._uploadLinkBaseUrl; } + set { this._uploadLinkBaseUrl = value; } + } + + public virtual CenterDevice.Rest.Clients.OAuth.IOAuthClientConfiguration OAuthConfiguration() + { + return new CenterDevice.Rest.Clients.OAuth.OAuthEndpointConfiguration(this.BasePath, this.UserAgent); + } + + /// + /// Gets or sets the default header. + /// + public virtual IDictionary DefaultHeader { get; set; } + + /// + /// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds. + /// + public virtual int Timeout { get; set; } + + /// + /// Gets or sets the HTTP user agent. + /// + /// Http user agent. + public virtual string UserAgent { get; set; } + + ///// + ///// Gets or sets the client number (HTTP basic authentication). + ///// + ///// The client number. + //public virtual string ClientNumber { get; set; } + + /// + /// Gets or sets the username (HTTP basic authentication). + /// + /// The username. + public virtual string Username { get; set; } + + ///// + ///// Gets or sets the name of the organisation (HTTP basic authentication). + ///// + ///// The organisation name. + //public virtual string OrganisationName { get; set; } + + /// + /// Gets or sets the password (HTTP basic authentication). + /// + /// The password. + public virtual string Password { get; set; } + + /// + /// Gets the API key with prefix. + /// + /// API key identifier (authentication scheme). + /// API key with prefix. + public string GetApiKeyWithPrefix(string apiKeyIdentifier) + { + var apiKeyValue = ""; + ApiKey.TryGetValue(apiKeyIdentifier, out apiKeyValue); + var apiKeyPrefix = ""; + if (ApiKeyPrefix.TryGetValue(apiKeyIdentifier, out apiKeyPrefix)) + return apiKeyPrefix + " " + apiKeyValue; + else + return apiKeyValue; + } + + /// + /// Gets or sets the access token for OAuth2 authentication. + /// + /// The access token. + public virtual string AccessToken { get; set; } + + /// + /// Gets or sets the temporary folder path to store the files downloaded from the server. + /// + /// Folder path. + public virtual string TempFolderPath + { + get { return _tempFolderPath; } + + set + { + if (string.IsNullOrEmpty(value)) + { + _tempFolderPath = Path.GetTempPath(); + return; + } + + // create the directory if it does not exist + if (!Directory.Exists(value)) + { + Directory.CreateDirectory(value); + } + + // check if the path contains directory separator at the end + if (value[value.Length - 1] == Path.DirectorySeparatorChar) + { + _tempFolderPath = value; + } + else + { + _tempFolderPath = value + Path.DirectorySeparatorChar; + } + } + } + + /// + /// Gets or sets the date time format used when serializing in the ApiClient + /// By default, it's set to ISO 8601 - "o", for others see: + /// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx + /// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx + /// No validation is done to ensure that the string you're providing is valid + /// + /// The DateTimeFormat string + public virtual string DateTimeFormat + { + get { return _dateTimeFormat; } + set + { + if (string.IsNullOrEmpty(value)) + { + // Never allow a blank or null string, go back to the default + _dateTimeFormat = ISO8601_DATETIME_FORMAT; + return; + } + + // Caution, no validation when you choose date time format other than ISO 8601 + // Take a look at the above links + _dateTimeFormat = value; + } + } + + /// + /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name. + /// + /// The prefix of the API key. + public virtual IDictionary ApiKeyPrefix + { + get { return _apiKeyPrefix; } + set + { + if (value == null) + { + throw new InvalidOperationException("ApiKeyPrefix collection may not be null."); + } + _apiKeyPrefix = value; + } + } + + /// + /// Gets or sets the API key based on the authentication name. + /// + /// The API key. + public virtual IDictionary ApiKey + { + get { return _apiKey; } + set + { + if (value == null) + { + throw new InvalidOperationException("ApiKey collection may not be null."); + } + _apiKey = value; + } + } + + #endregion Properties + + #region Methods + + /// + /// Add default header. + /// + /// Header field name. + /// Header field value. + /// + public void AddDefaultHeader(string key, string value) + { + DefaultHeader[key] = value; + } + + /// + /// Creates a new based on this instance. + /// + /// + internal CenterDevice.Rest.Clients.CenterDeviceClient CreateApiClient() + { + return new CenterDevice.Rest.Clients.CenterDeviceClient( + null, + this) + { + Config = this + }; + } + + + /// + /// Returns a string with essential information for debugging. + /// + public static String ToDebugReport() + { + String report = "C# SDK (CompuMaster.CenterDevice) Debug Report:\n"; + report += " OS: " + System.Environment.OSVersion + "\n"; + report += " .NET Framework Version: " + System.Environment.Version + "\n"; + report += " Version of the API: 0.1.0\n"; + report += " SDK Package Version: 1.0.0\n"; + + return report; + } + + /// + /// Add Api Key Header. + /// + /// Api Key name. + /// Api Key value. + /// + public void AddApiKey(string key, string value) + { + ApiKey[key] = value; + } + + /// + /// Sets the API key prefix. + /// + /// Api Key name. + /// Api Key value. + public void AddApiKeyPrefix(string key, string value) + { + ApiKeyPrefix[key] = value; + } + + #endregion Methods + } +} diff --git a/CenterDevice.Rest/Rest/Clients/CenterDeviceErrorHandler.cs b/CenterDevice.Rest/Rest/Clients/CenterDeviceErrorHandler.cs new file mode 100644 index 0000000..2a63fcf --- /dev/null +++ b/CenterDevice.Rest/Rest/Clients/CenterDeviceErrorHandler.cs @@ -0,0 +1,59 @@ +using CenterDevice.Rest; +using CenterDevice.Rest.Clients.OAuth; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CenterDevice.Rest.Clients +{ + public class CenterDeviceErrorHandler : CenterDevice.Rest.Clients.IRestClientErrorHandler + { + /// + /// Configuration for accessing CenterDevice API + /// + public CenterDeviceErrorHandler(string loginEMailAddress, CenterDevice.Rest.Clients.OAuth.IOAuthInfoProvider oAuthProvider) + { + this.OAuthProvider = oAuthProvider; + this.LoginEMailAddress = loginEMailAddress; + } + + public CenterDevice.Rest.Clients.OAuth.IOAuthInfoProvider OAuthProvider { get; set; } + public string LoginEMailAddress { get; set; } + + public OAuthInfo RefreshToken(OAuthInfo oAuthInfo) + { + return new OAuthInfo(this.LoginEMailAddress, this.OAuthProvider.GetOAuthInfo(this.LoginEMailAddress)); + } + + public void ValidateResponse(global::RestSharp.IRestResponse result) + { + if (result.StatusCode >= System.Net.HttpStatusCode.InternalServerError) + throw new System.Net.WebException("Server error", System.Net.WebExceptionStatus.UnknownError); + } + + ///// + ///// Configuration for accessing CenterDevice API + ///// + //public CenterDeviceErrorHandler(string loginEMailAddress, CenterDeviceOAuthInfoProvider oAuthProvider) + //{ + // this.OAuthProvider = oAuthProvider; + // this.LoginEMailAddress = loginEMailAddress; + //} + + //public CenterDeviceOAuthInfoProvider OAuthProvider { get; set; } + //public string LoginEMailAddress { get; set; } + + //public OAuthInfo RefreshToken(OAuthInfo oAuthInfo) + //{ + // return new OAuthInfo(this.LoginEMailAddress, this.OAuthProvider.CenterDeviceClient.Token); + //} + + //public void ValidateResponse(global::RestSharp.IRestResponse result) + //{ + // if (result.StatusCode >= System.Net.HttpStatusCode.InternalServerError) + // throw new System.Net.WebException("Server error", System.Net.WebExceptionStatus.UnknownError); + //} + } +} \ No newline at end of file diff --git a/CenterDevice.Rest/Rest/Clients/CenterDeviceOAuthInfoProvider.cs b/CenterDevice.Rest/Rest/Clients/CenterDeviceOAuthInfoProvider.cs new file mode 100644 index 0000000..fa5f699 --- /dev/null +++ b/CenterDevice.Rest/Rest/Clients/CenterDeviceOAuthInfoProvider.cs @@ -0,0 +1,38 @@ +using CenterDevice.Rest; +using CenterDevice.Rest.Clients.OAuth; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CenterDevice.Rest.Clients +{ + public class CenterDeviceOAuthInfoProvider : CenterDevice.Rest.Clients.OAuth.IOAuthInfoProvider + { + /// + /// Configuration for accessing CenterDevice API + /// + public CenterDeviceOAuthInfoProvider() + { + } + + /// + /// Configuration for accessing CenterDevice API + /// + public CenterDeviceOAuthInfoProvider(CenterDevice.Rest.Clients.CenterDeviceClient centerDeviceClient) + { + this.CenterDeviceClient = centerDeviceClient; + } + + public CenterDevice.Rest.Clients.CenterDeviceClient CenterDeviceClient { get; set; } + + private OAuthInfo getOAuthInfo = null; + public OAuthInfo GetOAuthInfo(string userId) + { + if ((getOAuthInfo == null) || (getOAuthInfo.UserId != userId)) + this.getOAuthInfo = new CenterDevice.Rest.Clients.OAuth.OAuthInfo(CenterDeviceClient.Config.Username, CenterDeviceClient.Token); + return this.getOAuthInfo; + } + } +} \ No newline at end of file diff --git a/CenterDevice.Rest/Rest/Clients/Collections/CollectionsResults.cs b/CenterDevice.Rest/Rest/Clients/Collections/CollectionsResults.cs index d92abed..709984f 100644 --- a/CenterDevice.Rest/Rest/Clients/Collections/CollectionsResults.cs +++ b/CenterDevice.Rest/Rest/Clients/Collections/CollectionsResults.cs @@ -53,7 +53,7 @@ public bool? HasDocuments return null; } } - public List Documents; + public List Documents; [DeserializeAs(Name = RestApiConstants.ARCHIVED_DATE)] public DateTime? ArchivedDate { get; set; } diff --git a/CenterDevice.Rest/Rest/Clients/DiagnosticTools.cs b/CenterDevice.Rest/Rest/Clients/DiagnosticTools.cs index 7d75894..39c4a1f 100644 --- a/CenterDevice.Rest/Rest/Clients/DiagnosticTools.cs +++ b/CenterDevice.Rest/Rest/Clients/DiagnosticTools.cs @@ -71,7 +71,7 @@ static StringBuilder PrintFolders(CenterDevice.Rest.Clients.Collections.Collecti return result; } - static StringBuilder PrintSubFolders(Rest.Clients.Folders.Folder parentFolder) + static StringBuilder PrintSubFolders(CenterDevice.Rest.Clients.Folders.Folder parentFolder) { var result = new StringBuilder(); if ((parentFolder.SubFolders != null) && (parentFolder.SubFolders.Count != 0)) @@ -82,7 +82,7 @@ static StringBuilder PrintSubFolders(Rest.Clients.Folders.Folder parentFolder) return result; } - private static StringBuilder PrintSubFolders(List Folders) + private static StringBuilder PrintSubFolders(List Folders) { var result = new StringBuilder(); var sb = new StringBuilder(); @@ -139,7 +139,7 @@ private static StringBuilder PrintSubFolders(List F return result; } - static StringBuilder PrintFiles(List documents) + static StringBuilder PrintFiles(List documents) { var result = new StringBuilder(); if (documents != null) diff --git a/CenterDevice.Rest/Rest/Clients/Folders/Folder.cs b/CenterDevice.Rest/Rest/Clients/Folders/Folder.cs index 3200c8c..9881da1 100644 --- a/CenterDevice.Rest/Rest/Clients/Folders/Folder.cs +++ b/CenterDevice.Rest/Rest/Clients/Folders/Folder.cs @@ -33,7 +33,7 @@ public bool? HasSubFolders } } - public List Documents; + public List Documents; public string Link { get; set; } diff --git a/CenterDevice.Rest/Rest/Clients/OAuth/OAuthInfo.cs b/CenterDevice.Rest/Rest/Clients/OAuth/OAuthInfo.cs index d5a3860..8449f63 100644 --- a/CenterDevice.Rest/Rest/Clients/OAuth/OAuthInfo.cs +++ b/CenterDevice.Rest/Rest/Clients/OAuth/OAuthInfo.cs @@ -2,6 +2,20 @@ { public class OAuthInfo { + public OAuthInfo() + { + } + + public OAuthInfo(string loginEMailAddress, OAuthInfo token) + { + this.Email = loginEMailAddress; + //TODO: what to do with token? + } + + //public OAuthInfo(string loginEMailAddress, CenterDevice.Rest.Model.TokenResponse centerDeviceToken) + //{ + //} + public string UserId { get; set; } public string Email { get; set; } public string TenantId { get; set; } diff --git a/CenterDevice.Rest/Rest/Clients/OAuth/OAuthTokenEndpointConfiguration.cs b/CenterDevice.Rest/Rest/Clients/OAuth/OAuthTokenEndpointConfiguration.cs new file mode 100644 index 0000000..cfebb60 --- /dev/null +++ b/CenterDevice.Rest/Rest/Clients/OAuth/OAuthTokenEndpointConfiguration.cs @@ -0,0 +1,42 @@ +using CenterDevice.Rest.Clients.OAuth; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CenterDevice.Rest.Clients.OAuth +{ + public class OAuthEndpointConfiguration : CenterDevice.Rest.RestClientConfiguration, CenterDevice.Rest.Clients.OAuth.IOAuthClientConfiguration + { + /// + /// Default configuration for accessing the token endpoint of CenterDevice API + /// + public OAuthEndpointConfiguration(string userAgent) : base(userAgent) + { + } + + /// + /// Custom configuration for accessing the token endpoint of CenterDevice API + /// + public OAuthEndpointConfiguration(string baseAddress, string userAgent) : base(baseAddress, userAgent) + { + } + + public string ClientId { get; set; } + + public string ClientSecret { get; set; } + + public string RedirectUri { get; set; } + + string IOAuthClientConfiguration.ClientId => this.ClientId; + + string IOAuthClientConfiguration.ClientSecret => this.ClientSecret; + + string IOAuthClientConfiguration.RedirectUri => this.RedirectUri; + + string IRestClientConfiguration.BaseAddress => this.BaseAddress; + + string IRestClientConfiguration.UserAgent => this.UserAgent; + } +} diff --git a/CenterDevice.Rest/Rest/Clients/RestClientConfiguration.cs b/CenterDevice.Rest/Rest/Clients/RestClientConfiguration.cs new file mode 100644 index 0000000..6652149 --- /dev/null +++ b/CenterDevice.Rest/Rest/Clients/RestClientConfiguration.cs @@ -0,0 +1,31 @@ +namespace CenterDevice.Rest +{ + public class RestClientConfiguration : IRestClientConfiguration + { + /// + /// Default configuration for accessing the token endpoint of CenterDevice API + /// + public RestClientConfiguration(string userAgent) + { + this.BaseAddress = "https://auth.centerdevice.de/token"; + this.UserAgent = userAgent; + } + + /// + /// Custom configuration for accessing the token endpoint of CenterDevice API + /// + public RestClientConfiguration(string baseAddress, string userAgent) + { + this.BaseAddress = baseAddress; + this.UserAgent = userAgent; + } + + public string BaseAddress { get; set; } + + public string UserAgent { get; set; } + + string IRestClientConfiguration.BaseAddress => this.BaseAddress; + + string IRestClientConfiguration.UserAgent => this.UserAgent; + } +} diff --git a/CenterDevice.SampleApp/Program.cs b/CenterDevice.SampleApp/Program.cs index c3f6469..1241e48 100644 --- a/CenterDevice.SampleApp/Program.cs +++ b/CenterDevice.SampleApp/Program.cs @@ -11,25 +11,33 @@ static void Main() { System.Console.WriteLine("PLEASE NOTE: Following user input will be buffered in directory " + System.IO.Path.GetTempPath()); string username = InputLine("username"); - string customerno = InputLine("customer no."); + //string customerno = InputLine("customer no."); string password = InputLine("password"); try { + string ClientCredentials = username + ":" + password; + string EncodedClientCredentials = System.Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(ClientCredentials)); + System.Console.WriteLine("Authorization header:\nAuthorization: Basic " + EncodedClientCredentials); + System.Console.WriteLine(); + //Authorize initially with user credentials -> recieved access token will be saved for following requests //TODO: somethine like CenterDeviceClient.AuthorizeWithUserCredentials(username, customerno, password); - //System.Console.WriteLine("Authorization successful, future requests can be executed with access token:\n" + CenterDeviceClient.Token.AccessToken); - //System.Console.WriteLine(); + CenterDevice.Rest.Clients.CenterDeviceClient CenterDeviceClient = new CenterDevice.Rest.Clients.CenterDeviceClient(); + CenterDeviceClient.AuthorizeWithUserCredentials(username, password); + //CenterDeviceClient.AuthorizeWithUserCredentials(username, customerno, password); + System.Console.WriteLine("Authorization successful, future requests can be executed with access token:\n" + CenterDeviceClient.Token.access_token); + System.Console.WriteLine(); //Create IO client for CenterDevice - CenterDevice.IO.CenterDeviceIOClient IOClient = null; - /* TODO:something like - CenterDevice.IO.CenterDeviceIOClient IOClient = new CenterDevice.IO.CenterDeviceIOClient( - new CenterDevice.Rest.Clients.CenterDeviceClient( - oAuthInfoProvider, configuration, errorHandler - ), - userID); //TODO: provide arguments as usual for CenterDevice REST client - */ + CenterDevice.IO.CenterDeviceIOClient IOClient = new CenterDevice.IO.CenterDeviceIOClient(CenterDeviceClient); + //CenterDevice.IO.CenterDeviceIOClient IOClient = new CenterDevice.IO.CenterDeviceIOClient( + // new CenterDevice.Rest.Clients.CenterDeviceClient( + // oAuthInfoProvider, + // configuration.OAuthConfiguration(), + // new CenterDevice.Rest.Clients.CenterDeviceErrorHandler(username, oAuthInfoProvider) + // ), + // username); //TODO: provide arguments as usual for CenterDevice REST client //Show available directory structure if (false) From 1049c1b0ce0d44ef52b0bd736a445dc973e48b88 Mon Sep 17 00:00:00 2001 From: Jochen Wezel Date: Wed, 6 Apr 2022 19:11:17 +0200 Subject: [PATCH 2/2] Update CenterDevice.Rest.csproj --- CenterDevice.Rest/CenterDevice.Rest.csproj | 334 +++------------------ 1 file changed, 48 insertions(+), 286 deletions(-) diff --git a/CenterDevice.Rest/CenterDevice.Rest.csproj b/CenterDevice.Rest/CenterDevice.Rest.csproj index 3f8aa3d..38c2291 100644 --- a/CenterDevice.Rest/CenterDevice.Rest.csproj +++ b/CenterDevice.Rest/CenterDevice.Rest.csproj @@ -1,298 +1,60 @@ - - - + + - Debug - AnyCPU - {6FDBDA8A-EE11-46CB-B416-759F0800420B} - Library - Properties - CenterDevice.Rest + netstandard2.0;netcoreapp3.1;net5.0;net48 CompuMaster.CenterDevice.Rest - v4.6.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 + 2021.07.26.100 + MIT + https://github.com/CompuMasterGmbH/CompuMaster.CenterDevice.IO + Copyright © 2017-2021 CenterDevice GmbH, Bonn/Germany and CompuMaster GmbH, Emmelshausen/Germany + A client for CenterDevice REST API + CompuMaster GmbH + CenterDevice.Rest + logo_64x64.png + https://github.com/CompuMasterGmbH/CompuMaster.CenterDevice.IO.git + git + CompuMaster CenterDevice IO Client + true + Debug;Release;CI_CD + Jochen Wezel + favicon.ico + + + bin\Debug\ + Off + + + true + full + true + true + bin\CI_CD\ + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - false - - - - - - - true - bin\x64\Debug\ - DEBUG;TRACE - full - x64 - prompt - MinimumRecommendedRules.ruleset + pdbonly + false + true + true + bin\Release\ + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - - bin\x64\Release\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset + + bin\Debug\CompuMaster.CenterDevice.Rest.xml - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - - - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset + + bin\Release\CompuMaster.CenterDevice.Rest.xml - - ..\packages\log4net.2.0.9\lib\net45\log4net.dll - - - ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Ninject.3.3.4\lib\net45\Ninject.dll - - - ..\packages\RestSharp.106.11.4\lib\net452\RestSharp.dll - - - - - - - - - - - + + True + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - REM Create a NuGet package for this project and place the .nupkg file in the project's output directory. -REM If you see this in Visual Studio's Error List window, check the Output window's Build tab for the actual error. -rem ECHO Creating NuGet package in Post-Build event... -rem PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '$(ProjectDir)_CreateNewNuGetPackage\DoNotModify\CreateNuGetPackage.ps1' -ProjectFilePath '$(ProjectPath)' -OutputDirectory '$(TargetDir)' -BuildConfiguration '$(ConfigurationName)' -BuildPlatform '$(PlatformName)'" - - \ No newline at end of file