Forráskód Böngészése

add UserGetAPIKeyCommand

extends AbstractArgument to work with enum values (QConsole 1.0.6.0)
Dalibor Votruba 4 éve
szülő
commit
cce850ef52

+ 1 - 0
AppServer/Business/ErrorCodes.txt

@@ -23,6 +23,7 @@ Business.StorageService (1300 - 1399)
 
 Business.WorkspaceService (1400 - 1499)
 1400	Workspace with APIKey '{0}' not exists or API password is not valid!
+1410	User '{0}' has any default workspace set!
 
 Business.DocumentService (1500 - 1599)
 1500	Invalid document '{0}' [{1}] state '{2}' for operation '{3}'. Operation cancelled.

+ 14 - 3
AppServer/Business/Services/UserService.cs

@@ -4,6 +4,7 @@ using System.Globalization;
 using System.Linq;
 using System.Security.Principal;
 using System.Threading.Tasks;
+using BO.AppServer.Business.Exceptions;
 using BO.AppServer.Business.Mapper;
 using BO.AppServer.Business.Security;
 using BO.AppServer.Business.Services.Base;
@@ -69,10 +70,20 @@ namespace BO.AppServer.Business.Services
             return new ResultsValueDto<UserRDto>(users.MapList<User, UserRDto>());
         }
 
-        public async Task<ResultValueDto<UserRDto>> GetUserAsync(long userId)
+
+        public async Task<ResultValueDto<UserRDto>> GetUserAsync(IdentificationTypeEnum identificationType, string identificationValue)
         {
-            var user = _repoUser.Get(new []{userId}).FirstOrDefault();
-            return new ResultValueDto<UserRDto>(user.Map<User, UserRDto>());
+            var user = identificationType == IdentificationTypeEnum.Id ?
+                _repoUser.Get(ArgumentAsLong(nameof(identificationValue), identificationValue))
+                : _repoUser.GetByName(identificationValue);
+
+
+            if (user == null)
+                throw new NoDataException();
+            
+            // gather rest of data
+            var result = new ResultValueDto<UserRDto>(user.Map<User, UserRDto>());
+            return result;
         }
 
         public async Task<ResultValueDto<UserRDto>> CreateUserAsync(UserCDto newUser)

+ 18 - 0
AppServer/Business/Services/WorkspaceService.cs

@@ -99,6 +99,24 @@ namespace BO.AppServer.Business.Services
                     }
                     workspaces = _repoWorkspace.GetAllByOwner(owner, paging).ToList();
                     break;
+                case WorkspaceScopeEnums.MyDefault:
+                    owner = _repoUser.GetByName(ownerUserName);
+                    if (owner == null)
+                    {
+                        var exc = new EntityNotExistsException(typeof(User), ownerUserName, 0);
+                        Log.LogWarning(exc.Message);
+                        throw exc;
+                    }
+                    var workspace = _repoWorkspace.GetDefaultByOwner(owner);
+                    if (workspace == null)
+                    {
+                        var exc = new CodeException(1410,$"User '{ownerUserName}' has any default workspace set!");
+                        Log.LogWarning(exc.Message);
+                        throw exc;
+                    }
+
+                    workspaces = new List<Workspace>(new[] { workspace });
+                    break;
             }
 
             return new ResultsValueDto<WorkspaceRDto>(workspaces.MapList<Workspace, WorkspaceRDto>());

+ 9 - 1
AppServer/Data/Repository/WorkspaceRepo.cs

@@ -76,4 +76,12 @@ public class WorkspaceRepo : EntityRepository<long,  Workspace>
             return userWorkspaceSet.Page(paging.IsDisabled ? (int?)null : paging.Page, paging.PageSize)
                 .Where(x => x.User == owner || owner==null).Select(x => x.Workspace);
         }
-    }
+
+        public Workspace GetDefaultByOwner(User owner)
+        {
+            if (owner == null)
+                throw new ArgumentNullException(nameof(owner));
+            var userWorkspaceSet = Context.GetDbSet<DbSet<UserWorkspace>>();
+            return userWorkspaceSet.Where(x => x.User == owner).Select(x=>x.Workspace).FirstOrDefault();
+        }
+}

+ 1 - 0
AppServer/Metadata/Dto/UserDto.cs

@@ -43,6 +43,7 @@ namespace BO.AppServer.Metadata.Dto
         public bool IsEnabled { get; set; }
         
         public string[] Roles { get; set; }
+
     }
     #endregion
 

+ 2 - 0
AppServer/Metadata/Dto/WorkspaceDto.cs

@@ -46,6 +46,8 @@ namespace BO.AppServer.Metadata.Dto
         public int DocumentsCount { get; set; }
         public BoAuditDto Audit { get; set; }
         public IEnumerable<StructureRDto> Structures { get; set; }
+
+        public string ApiKeyNormalized => Apikey.ToString("D");
     }
 
     #endregion

+ 8 - 1
AppServer/Metadata/Enums/ScopeEnums.cs

@@ -68,7 +68,14 @@
         All,
         Empty,
         NotEmpty,
-        My
+        /// <summary>
+        /// Only my workspaces
+        /// </summary>
+        My,
+        /// <summary>
+        /// Only my default workspace
+        /// </summary>
+        MyDefault
     }
 
     public enum DocumentsScopeEnums

+ 5 - 3
AppServer/Metadata/Metadata.csproj

@@ -10,12 +10,14 @@
     <ApplicationIcon>bo_dll.ico</ApplicationIcon>
   </PropertyGroup>
 
-  <ItemGroup>
-    <ProjectReference Include="..\..\Common\qdr.fnd.core.data.itfc\qdr.fnd.core.data.itfc.csproj" />
+  <ItemGroup>
+    <Compile Remove="Repository\**" />
+    <EmbeddedResource Remove="Repository\**" />
+    <None Remove="Repository\**" />
   </ItemGroup>
 
   <ItemGroup>
-    <Folder Include="Repository\" />
+    <ProjectReference Include="..\..\Common\qdr.fnd.core.data.itfc\qdr.fnd.core.data.itfc.csproj" />
   </ItemGroup>
 
 </Project>

+ 32 - 28
AppServer/Web/Properties/launchSettings.json

@@ -1,29 +1,33 @@
-{
-  "iisSettings": {
-    "windowsAuthentication": false,
-    "anonymousAuthentication": true,
-    "iisExpress": {
-      "applicationUrl": "http://localhost:5242",
-      "sslPort": 44306
-    }
-  },
-  "profiles": {
-    "IIS Express": {
-      "commandName": "IISExpress",
-      "launchBrowser": true,
-      "environmentVariables": {
-        "ASPNETCORE_ENVIRONMENT": "Development",
-        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
-      }
-    },
-    "AppServer": {
-      "commandName": "Project",
-      "launchBrowser": true,
-      "environmentVariables": {
-        "ASPNETCORE_ENVIRONMENT": "Development",
-        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
-      },
-      "applicationUrl": "https://192.168.1.101:5001;http://192.168.1.101:5000"
-    }
-  }
+{
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iis": {
+      "applicationUrl": "http://localhost/Web",
+      "sslPort": 0
+    },
+    "iisExpress": {
+      "applicationUrl": "http://localhost:5242",
+      "sslPort": 44306
+    }
+  },
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IIS",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
+      }
+    },
+    "AppServer": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
+      },
+      "applicationUrl": "https://localhost:5001;http://localhost:5000"
+    }
+  }
 }

+ 1 - 2
AppServer/Web/Services/ConsoleController.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
-using System.IO;
 using System.Threading.Tasks;
 using BO.AppServer.Business;
 using BO.AppServer.Business.Services;
@@ -52,7 +51,7 @@ namespace BO.AppServer.Web.Services
         public async Task<ResultValueDto<UserRDto>> GetUser(string ticket, IdentificationTypeEnum identificationType, string identificationValue)
         {
             CheckAccess(ticket);
-            return await Call(async () => await _srvUsers.GetUserAsync(1));
+            return await Call(async () => await _srvUsers.GetUserAsync(identificationType, identificationValue));
         }
 
         [HttpPost("{ticket}/user")]

+ 2 - 2
AppServer/Web/appsettings.Development.json

@@ -11,8 +11,8 @@
   },
   "Bo": {
     "System": {
-      "DbConnectionBO": "Server=(localdb)\\mssqllocaldb;Database=BO;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
-      "DbConnectionIF": "Server=(localdb)\\mssqllocaldb;Database=BO_IF;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
+      "DbConnectionBO": "Server=(localdb)\\MSSQLLocalDB;Database=BO;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
+      "DbConnectionIF": "Server=(localdb)\\MSSQLLocalDB;Database=BO_IF;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
       "SessionIdleTimeout": "00:05:00",
       "UseSSL": false,
       "AccountSystem": {

+ 2 - 2
AppServer/Web/appsettings.json

@@ -11,8 +11,8 @@
   },
   "Bo": {
     "System": {
-      "DbConnectionBO": "Server=(localdb)\\mssqllocaldb;Database=BO;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
-      "DbConnectionIF": "Server=(localdb)\\mssqllocaldb;Database=BO_IF;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
+      "DbConnectionBO": "Server=(localdb)\\MSSQLLocalDB;Database=BO;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
+      "DbConnectionIF": "(localdb)\\MSSQLLocalDB;Database=BO_IF;Trusted_Connection=True;", // For localDB use Server=(localdb)\mssqllocaldb, for SqlServer use Server=(local)
       "SessionIdleTimeout": "00:05:00",
       "UseSSL": true,
       "AccountSystem": {

+ 14 - 3
Common/qdr.fnd.core.qconsole/Command/Base/AbstractCommand.cs

@@ -343,15 +343,15 @@ namespace Quadarax.Foundation.Core.QConsole.Command.Base
         protected TValue GetArgumentValueOrDefault<TValue>(string code, TValue defalutValue)
         {
             if (!ContainsArgument(code)) return defalutValue;
-            var arg = GetArgument(code);
-            var value = arg.Value.Get() ?? arg.DefaultValue.Get();
-            return (TValue) value;
+            return (TValue) GetArgumentValueOrDefault<TValue>(code);
         }
         protected TValue GetArgumentValueOrDefault<TValue>(string code)
         {
             if (!ContainsArgument(code)) throw new ArgumentOutOfRangeException(code, $"Argument '{code}' not defined.");
             var arg = GetArgument(code);
             var value = arg.Value.Get() ?? arg.DefaultValue.Get();
+            if (typeof(TValue).IsEnum)
+                return (TValue)Enum.Parse(typeof(TValue), value?.ToString(),true);
             return (TValue) value;
         }
 
@@ -362,7 +362,18 @@ namespace Quadarax.Foundation.Core.QConsole.Command.Base
             return arg.Value.HasValue;
         }
 
+        protected void ValidateArgumentValueEnum(string argumentName, Type enumType)
+        {
+            var argVal = GetArgumentValueOrDefault<string>(argumentName);
+            if (!Enum.GetNames(enumType).Select(x => x.ToLower()).Contains(argVal.ToLower()))
+                throw new ArgumentOutOfRangeException(
+                    $"Argument '{argumentName}' value must be set as following: {string.Join(",", Enum.GetNames(enumType))}");
 
+        }
+        protected void ValidateArgumentValueEnum<TEnum>(string argumentName) where TEnum : Enum
+        {
+            ValidateArgumentValueEnum(argumentName, typeof(TEnum));
+        }
         protected bool ContainsArgument(string code)
         {
             return _arguments.ContainsKey(code);

+ 2 - 2
Common/qdr.fnd.core.qconsole/qdr.fnd.core.qconsole.csproj

@@ -7,8 +7,8 @@
     <DelaySign>false</DelaySign>
     <RootNamespace>Quadarax.Foundation.Core.QConsole</RootNamespace>
     <ApplicationIcon>..\quadarax_dll.ico</ApplicationIcon>
-    <AssemblyVersion>1.0.5.0</AssemblyVersion>
-    <FileVersion>1.0.5.0</FileVersion>
+    <AssemblyVersion>1.0.6.0</AssemblyVersion>
+    <FileVersion>1.0.6.0</FileVersion>
   </PropertyGroup>
 
   <ItemGroup>

+ 18 - 0
Console/Commands/Enums/OutputTargetEnum.cs

@@ -0,0 +1,18 @@
+namespace BO.Console.Commands.Enums
+{
+    internal enum OutputTargetEnum
+    {
+        /// <summary>
+        /// Nothing happened. No output target
+        /// </summary>
+        No,
+        /// <summary>
+        /// Copy to clipboard
+        /// </summary>
+        Clp,
+        /// <summary>
+        /// Copy to env. variable
+        /// </summary>
+        Var
+    }
+}

+ 9 - 0
Console/Commands/Enums/ValueTypeApiKeyEnum.cs

@@ -0,0 +1,9 @@
+namespace BO.Console.Commands.Enums
+{
+    internal enum ValueTypeApiKeyEnum
+    {
+        ApiKey, 
+        ApiPwd,
+        ApiBoth
+    }
+}

+ 122 - 0
Console/Commands/User/UserGetAPIKeyCommand.cs

@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using BO.AppServer.Metadata.Enums;
+using BO.Console.Commands.Base;
+using BO.Console.Commands.Enums;
+using Quadarax.Foundation.Core.QConsole;
+using Quadarax.Foundation.Core.QConsole.Argument;
+using Quadarax.Foundation.Core.QConsole.Attributes;
+using Quadarax.Foundation.Core.QConsole.Value;
+using Quadarax.Foundation.Core.Value;
+using Quadarax.Foundation.Core.Value.Extensions;
+// ReSharper disable InconsistentNaming
+
+namespace BO.Console.Commands.User
+{
+    [CommandDefinition]
+    internal class UserGetAPIKeyCommand : AbstractGetCommand
+    {
+        #region *** Constants ***
+        private const string CS_CMD_USERGET_NAME = "user_getapikey";
+        private const string CS_CMD_USERGET_DESCR = "Get default single user workspace api-key or api-password and process result.";
+
+        private const string CS_ARG_NAME_TYPE = "outt";
+        private const string CS_ARG_HINT_TYPE = "<output_target>";
+        private const string CS_ARG_DESC_TYPE = "Defines output target (no - none, clp - clipboard,var - env. variable). Default is no.";
+
+
+
+        private const string CS_ARG_NAME_VALUE = "vt";
+        private const string CS_ARG_HINT_VALUE = "<value_type>";
+        private const string CS_ARG_DESC_VALUE = "Defines value type to return (apikey,apipwd,apiboth). Default is apiboth.";
+
+        private const string CS_ENV_VAR_VALUE_KEY = "bo_apikey";
+        private const string CS_ENV_VAR_VALUE_PWD = "bo_apipwd";
+        #endregion
+
+        #region *** Properties ***
+
+        public override string Name => CS_CMD_USERGET_NAME;
+        public override string Description => CS_CMD_USERGET_DESCR;
+
+        private OutputTargetEnum Target { get; set; }
+        private ValueTypeApiKeyEnum ValueType { get; set; }
+        #endregion
+
+        #region *** Constructor ***
+        public UserGetAPIKeyCommand(Engine engine) : base(engine)
+        {
+        }
+        #endregion
+
+        #region *** EXECUTE ***
+        protected override Result OnExecute()
+        {
+            var user = Client.GetUserAsync(IdentificationType, IdentificationValue).Result;
+            WriteInfo($"User '{user.Name}' [{user.Id}] validated (Created:{user.Created.ToFileShortDateTimeString()}, Logged:{user.LastLogged?.ToFileShortDateTimeString()})  ");
+            var workspaces = Client.GetWorkspacesAsync(WorkspaceScopeEnums.MyDefault, user.Name).Result;
+            if (!workspaces.Any())
+                throw new Exception($"No default workspace for user '{user.Name}' set.");
+            var workspace = workspaces.First();
+            WriteInfo($"User has default workspace named '{workspace.Name}' [{workspace.Id}] (Created:{workspace.Audit.Created.ToFileShortDateTimeString()}, Changed:{workspace.Audit.Changed?.ToFileShortDateTimeString()})");
+            WriteCaption($"APIKey: {workspace.ApiKeyNormalized}");
+            WriteInfo($"APIPassword: {workspace.Apipassword}");
+            var value = ValueType == ValueTypeApiKeyEnum.ApiKey
+                ? workspace.ApiKeyNormalized
+                : ValueType == ValueTypeApiKeyEnum.ApiPwd ? workspace.Apipassword : workspace.ApiKeyNormalized + ";" + workspace.Apipassword;
+            switch (Target)
+            {
+                case OutputTargetEnum.No:
+                    WriteCaption("No output target set.");
+                    break;
+                case OutputTargetEnum.Clp:
+                    TextCopy.ClipboardService.SetText(value);
+                    WriteCaption($"Value '{value}' was set to clipboard.");
+                    break;
+                case OutputTargetEnum.Var:
+                    if (ValueType == ValueTypeApiKeyEnum.ApiKey || ValueType == ValueTypeApiKeyEnum.ApiBoth)
+                    {
+                        Environment.SetEnvironmentVariable(CS_ENV_VAR_VALUE_KEY, workspace.ApiKeyNormalized, EnvironmentVariableTarget.Process);
+                        WriteCaption($"Value '{workspace.ApiKeyNormalized}' was set to environment value '{CS_ENV_VAR_VALUE_KEY}' in scope current process.");
+                    }
+
+                    if (ValueType == ValueTypeApiKeyEnum.ApiPwd || ValueType == ValueTypeApiKeyEnum.ApiBoth)
+                    {
+
+                        Environment.SetEnvironmentVariable(CS_ENV_VAR_VALUE_PWD, workspace.Apipassword, EnvironmentVariableTarget.Process);
+                        WriteCaption($"Value '{workspace.Apipassword}' was set to environment value '{CS_ENV_VAR_VALUE_PWD}' in scope current process.");
+                    }
+
+                    WriteInfo($"To use environment value: use %{CS_ENV_VAR_VALUE_KEY}% and/or %{CS_ENV_VAR_VALUE_PWD}%");
+                    break;
+            }
+            return new Result();
+        }
+        #endregion
+
+        #region *** Private Overrides ***
+        protected override void OnValidateArguments()
+        {
+            base.OnValidateArguments();
+            ValidateArgumentValueEnum<OutputTargetEnum>(CS_ARG_NAME_TYPE);
+            ValidateArgumentValueEnum<ValueTypeApiKeyEnum>(CS_ARG_NAME_VALUE);
+
+            Target = GetArgumentValueOrDefault<OutputTargetEnum>(CS_ARG_NAME_TYPE);
+            ValueType = GetArgumentValueOrDefault<ValueTypeApiKeyEnum>(CS_ARG_NAME_VALUE);
+        }
+
+        protected override IEnumerable<AbstractArgument> OnSetupArguments()
+        {
+            var args = base.OnSetupArguments().ToList();
+            args.Add(new NamedArgument(CS_ARG_NAME_TYPE, CS_ARG_DESC_TYPE, CS_ARG_HINT_TYPE, TypeValuesEnum.String, "no", false));
+            args.Add(new NamedArgument(CS_ARG_NAME_VALUE, CS_ARG_DESC_VALUE, CS_ARG_HINT_VALUE, TypeValuesEnum.String, "apiboth", false));
+            return args;
+        }
+
+        #endregion
+
+        #region *** Private operations ***
+        #endregion
+    }
+}

+ 1 - 0
Console/Console.csproj

@@ -22,6 +22,7 @@
 
   <ItemGroup>
     <PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
+    <PackageReference Include="TextCopy" Version="4.3.1" />
   </ItemGroup>
 
   <ItemGroup>

+ 7 - 7
Console/Properties/launchSettings.json

@@ -1,8 +1,8 @@
-{
-  "profiles": {
-    "Console": {
-      "commandName": "Project",
-      "commandLineArgs": "dbclear -srv:(localdb)\\mssqllocaldb -db:BO -isec"
-    }
-  }
+{
+  "profiles": {
+    "Console": {
+      "commandName": "Project",
+      "commandLineArgs": "user_getapikey -name:test -outt:clp"
+    }
+  }
 }

+ 2 - 1
Console/Samples/dbinstall.cmd

@@ -3,7 +3,8 @@ REM ** If BO database exists skip if -force argument no defined **
 REM ** If BO database exists delete database and creates new one if -force argument efined **
 REM ** Usage: dbinstall [-force] **
 @echo off
+call setenv.cmd
 set oldcd=%cd%
 cd %BOPath%
-%BOConsole% dbinstall -srv:(localdb)\mssqllocaldb -db:BO -isec %1
+%BOConsole% dbinstall -srv:(localdb)\mssqllocaldb -db:BO -isec %1%
 cd %oldcd%

+ 6 - 1
Console/Samples/upload_document_2_art.cmd

@@ -1,3 +1,8 @@
 REM ** Uploads 2 artifacts to one new created document (if not exists - otherwise append arts) in default workspace (api-key is defined in console.json) **
 REM ** AppServer must be started first / this script must be run in same directory as BO.Console**
-Bo.Console document_add -arts:doc1_file1.bin;doc1_file2.bin -force -user:test
+@echo off
+call setenv.cmd
+set oldcd=%cd%
+cd %BOPath% 
+%BOConsole% document_add -arts:%oldcd%\doc1_file1.bin;%oldcd%\doc1_file2.bin -force -user:test
+cd %oldcd%

+ 1 - 1
Console/console.json

@@ -1,5 +1,5 @@
 {
-  "api-base-url": "http://192.168.1.101:5000/api/",
+  "api-base-url": "http://localhost:5000/api/",
   "api-user": "Console",
   "api-pwd": "A1Abastr0vA",
   "api-magic": "6DEC4167-57A6-4333-92DA-ADE009A97DE9",