From ecb452a645d348eb460a860074fcec5cdd078d8a Mon Sep 17 00:00:00 2001 From: Teemu Tossavainen Date: Fri, 7 Oct 2022 13:49:20 +0300 Subject: [PATCH 1/4] init --- ...AddUserToGroups_build_and_test_on_main.yml | 18 +++ ...AddUserToGroups_build_and_test_on_push.yml | 19 +++ .github/workflows/AddUserToGroups_release.yml | 12 ++ Frends.LDAP.AddUserToGroups/CHANGELOG.md | 5 + .../Frends.LDAP.AddUserToGroups.Tests.csproj | 22 +++ .../UnitTests.cs | 130 ++++++++++++++++++ .../Frends.LDAP.AddUserToGroups.sln | 40 ++++++ .../AddUserToGroups.cs | 57 ++++++++ .../Definitions/Connection.cs | 46 +++++++ .../Definitions/Input.cs | 19 +++ .../Definitions/Result.cs | 39 ++++++ .../Frends.LDAP.AddUserToGroups.csproj | 27 ++++ .../FrendsTaskMetadata.json | 7 + Frends.LDAP.AddUserToGroups/README.md | 30 ++++ README.md | 1 + 15 files changed, 472 insertions(+) create mode 100644 .github/workflows/AddUserToGroups_build_and_test_on_main.yml create mode 100644 .github/workflows/AddUserToGroups_build_and_test_on_push.yml create mode 100644 .github/workflows/AddUserToGroups_release.yml create mode 100644 Frends.LDAP.AddUserToGroups/CHANGELOG.md create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/Frends.LDAP.AddUserToGroups.Tests.csproj create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.sln create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Connection.cs create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Result.cs create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.csproj create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/FrendsTaskMetadata.json create mode 100644 Frends.LDAP.AddUserToGroups/README.md diff --git a/.github/workflows/AddUserToGroups_build_and_test_on_main.yml b/.github/workflows/AddUserToGroups_build_and_test_on_main.yml new file mode 100644 index 0000000..cba088b --- /dev/null +++ b/.github/workflows/AddUserToGroups_build_and_test_on_main.yml @@ -0,0 +1,18 @@ +name: AddUserToGroups build main + +on: + push: + branches: + - main + paths: + - 'Frends.LDAP.AddUserToGroups/**' + workflow_dispatch: + +jobs: + build: + uses: FrendsPlatform/FrendsTasks/.github/workflows/linux_build_main.yml@main + with: + workdir: Frends.LDAP.AddUserToGroups + prebuild_command: docker run -d -i --rm -p 10389:10389 dwimberger/ldap-ad-it + secrets: + badge_service_api_key: ${{ secrets.BADGE_SERVICE_API_KEY }} \ No newline at end of file diff --git a/.github/workflows/AddUserToGroups_build_and_test_on_push.yml b/.github/workflows/AddUserToGroups_build_and_test_on_push.yml new file mode 100644 index 0000000..1669fa7 --- /dev/null +++ b/.github/workflows/AddUserToGroups_build_and_test_on_push.yml @@ -0,0 +1,19 @@ +name: AddUserToGroups build test + +on: + push: + branches-ignore: + - main + paths: + - 'Frends.LDAP.AddUserToGroups/**' + workflow_dispatch: + +jobs: + build: + uses: FrendsPlatform/FrendsTasks/.github/workflows/linux_build_test.yml@main + with: + workdir: Frends.LDAP.AddUserToGroups + prebuild_command: docker run -d -i --rm -p 10389:10389 dwimberger/ldap-ad-it + secrets: + badge_service_api_key: ${{ secrets.BADGE_SERVICE_API_KEY }} + test_feed_api_key: ${{ secrets.TASKS_TEST_FEED_API_KEY }} \ No newline at end of file diff --git a/.github/workflows/AddUserToGroups_release.yml b/.github/workflows/AddUserToGroups_release.yml new file mode 100644 index 0000000..4b34e27 --- /dev/null +++ b/.github/workflows/AddUserToGroups_release.yml @@ -0,0 +1,12 @@ +name: AddUserToGroups release + +on: + workflow_dispatch: + +jobs: + build: + uses: FrendsPlatform/FrendsTasks/.github/workflows/release.yml@main + with: + workdir: Frends.LDAP.AddUserToGroups + secrets: + feed_api_key: ${{ secrets.TASKS_FEED_API_KEY }} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/CHANGELOG.md b/Frends.LDAP.AddUserToGroups/CHANGELOG.md new file mode 100644 index 0000000..9b9fc68 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## [1.0.0] - 2022-10-07 +### Added +- Initial implementation \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/Frends.LDAP.AddUserToGroups.Tests.csproj b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/Frends.LDAP.AddUserToGroups.Tests.csproj new file mode 100644 index 0000000..0f0ca79 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/Frends.LDAP.AddUserToGroups.Tests.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs new file mode 100644 index 0000000..e47e2bf --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs @@ -0,0 +1,130 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Frends.LDAP.AddUserToGroups.Definitions; +using Novell.Directory.Ldap; +namespace Frends.LDAP.AddUserToGroups.Tests; + +[TestClass] +public class UnitTests +{ + // Azure AD. + /* + private readonly int _port = 389; + private readonly string? _path = "CN=Users,DC=FRENDSTest01,DC=net"; + private readonly string? _dn = "CN=Tes Tuser,CN=Users,DC=FRENDSTest01,DC=net"; + private readonly string? _groupDn = "CN=Users,CN=Builtin,DC=FRENDSTest01,DC=net"; + private readonly string? _host = Environment.GetEnvironmentVariable("HiQ_AzureADTest_Address"); + private readonly string? _user = Environment.GetEnvironmentVariable("HiQ_AzureADTest_User"); + private readonly string? _pw = Environment.GetEnvironmentVariable("HiQ_AzureADTest_Password"); + */ + + /* + LDAP server to docker. + docker run -d -it --rm -p 10389:10389 dwimberger/ldap-ad-it + */ + private readonly string? _host = "127.0.0.1"; + private readonly int _port = 10389; + private readonly string? _user = "uid=admin,ou=system"; + private readonly string? _pw = "secret"; + private readonly string _path = "ou=users,dc=wimpi,dc=net"; + private readonly string? _dn = "CN=Tes Tuser,ou=users,dc=wimpi,dc=net"; + private readonly string? _groupDn = "cn=admin,ou=roles,dc=wimpi,dc=net"; + + Input? input; + Connection? connection; + + [TestInitialize] + public void StartUp() + { + try + { + CreateTestUsers(); + } + catch (Exception) + { + } + } + + [TestCleanup] + public void CleanUp() + { + try + { + DeleteUser(); + } + catch (Exception) + { + } + } + + [TestMethod] + public void Update_HandleLDAPError_Test() + { + input = new() + { + UserDistinguishedName = "CN=Common Name,CN=Users,DC=Example,DC=Com", + GroupDistinguishedName = "CN=Admins,DC=Example,DC=Com" + }; + connection = new() + { + Host = _host, + User = _user, + Password = _pw, + SecureSocketLayer = false, + Port = _port, + TLS = false, + }; + + var result = LDAP.AddUserToGroups(input, connection); + Assert.IsTrue(result.Success.Equals(false) && result.Error.Contains("No Such Object")); + } + + [TestMethod] + public void AddUserToGroups_Test() + { + input = new() + { + UserDistinguishedName = _dn, + GroupDistinguishedName = _groupDn + }; + connection = new() + { + Host = _host, + User = _user, + Password = _pw, + SecureSocketLayer = false, + Port = _port, + TLS = false, + }; + + var result = LDAP.AddUserToGroups(input, connection); + Assert.IsTrue(result.Success.Equals(true)); + } + + public void CreateTestUsers() + { + LdapConnection conn = new(); + conn.Connect(_host, _port); + conn.Bind(_user, _pw); + + var attributeSet = new LdapAttributeSet(); + attributeSet.Add(new LdapAttribute("objectclass", "user")); + attributeSet.Add(new LdapAttribute("cn", "Tes Tuser")); + attributeSet.Add(new LdapAttribute("givenname", "Tes")); + attributeSet.Add(new LdapAttribute("sn", "Tuser")); + + var entry = $"CN=Tes Tuser,{_path}"; + LdapEntry newEntry = new(entry, attributeSet); + conn.Add(newEntry); + conn.Disconnect(); + } + + public void DeleteUser() + { + LdapConnection conn = new(); + conn.Connect(_host, _port); + conn.Bind(_user, _pw); + conn.Delete($"CN=Tes Tuser,{_path}"); + conn.Delete($"CN=Tes Tuser,{_path}"); + conn.Disconnect(); + } +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.sln b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.sln new file mode 100644 index 0000000..69ffa70 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32319.34 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frends.LDAP.AddUserToGroups", "Frends.LDAP.AddUserToGroups\Frends.LDAP.AddUserToGroups.csproj", "{35C305C0-8108-4A98-BB1D-AFE5C926239E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{78F7F22E-6E20-4BCE-8362-0C558568B729}" + ProjectSection(SolutionItems) = preProject + CHANGELOG.md = CHANGELOG.md + ..\.github\workflows\AddUserToGroups_build_and_test_on_main.yml = ..\.github\workflows\AddUserToGroups_build_and_test_on_main.yml + ..\.github\workflows\AddUserToGroups_build_and_test_on_push.yml = ..\.github\workflows\AddUserToGroups_build_and_test_on_push.yml + ..\.github\workflows\AddUserToGroups_release.yml = ..\.github\workflows\AddUserToGroups_release.yml + README.md = README.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Frends.LDAP.AddUserToGroups.Tests", "Frends.LDAP.AddUserToGroups.Tests\Frends.LDAP.AddUserToGroups.Tests.csproj", "{57A63142-3694-4833-AA13-20233A6B57B0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {35C305C0-8108-4A98-BB1D-AFE5C926239E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35C305C0-8108-4A98-BB1D-AFE5C926239E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35C305C0-8108-4A98-BB1D-AFE5C926239E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35C305C0-8108-4A98-BB1D-AFE5C926239E}.Release|Any CPU.Build.0 = Release|Any CPU + {57A63142-3694-4833-AA13-20233A6B57B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57A63142-3694-4833-AA13-20233A6B57B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57A63142-3694-4833-AA13-20233A6B57B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57A63142-3694-4833-AA13-20233A6B57B0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8986D685-9988-4F5F-B8D9-E42A4E44BFED} + EndGlobalSection +EndGlobal diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs new file mode 100644 index 0000000..02a6941 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs @@ -0,0 +1,57 @@ +using Frends.LDAP.AddUserToGroups.Definitions; +using System.ComponentModel; +using Novell.Directory.Ldap; +using System; + +namespace Frends.LDAP.AddUserToGroups; + +/// +/// LDAP task. +/// +public class LDAP +{ + /// + /// Add user to Active Directory groups. + /// [Documentation](https://tasks.frends.com/tasks/frends-tasks/Frends.LDAP.AddUserToGroups) + /// + /// Input parameters. + /// Connection parameters. + /// Object { bool Success, string Error, string CommonName, string Path } + public static Result AddUserToGroups([PropertyTab] Input input, [PropertyTab] Connection connection) + { + if (string.IsNullOrWhiteSpace(connection.Host) || string.IsNullOrWhiteSpace(connection.User) || string.IsNullOrWhiteSpace(connection.Password)) + throw new Exception("AddUserToGroups error: Connection parameters missing."); + + LdapConnection conn = new(); + + try + { + var defaultPort = connection.SecureSocketLayer ? 636 : 389; + + conn.SecureSocketLayer = connection.SecureSocketLayer; + conn.Connect(connection.Host, connection.Port == 0 ? defaultPort : connection.Port); + if (connection.TLS) conn.StartTls(); + conn.Bind(connection.User, connection.Password); + + LdapModification[] mods = new LdapModification[1]; + var member = new LdapAttribute("member", input.UserDistinguishedName); + mods[0] = new LdapModification(LdapModification.Add, member); + conn.Modify(input.GroupDistinguishedName, mods); + + return new Result(true, null, input.UserDistinguishedName, input.GroupDistinguishedName); + } + catch (LdapException ex) + { + return new Result(false, ex.Message, input.UserDistinguishedName, input.GroupDistinguishedName); + } + catch (Exception ex) + { + throw new Exception($"AddUserToGroups error: {ex}"); + } + finally + { + if (connection.TLS) conn.StopTls(); + conn.Disconnect(); + } + } +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Connection.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Connection.cs new file mode 100644 index 0000000..6eb6f4e --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Connection.cs @@ -0,0 +1,46 @@ +using System.ComponentModel; +namespace Frends.LDAP.AddUserToGroups.Definitions; + +/// +/// Connection parameters. +/// +public class Connection +{ + /// + /// Host. + /// + /// adserver.westeurope.cloudapp.azure.com + public string Host { get; set; } + + /// + /// Port. Value 0 = use LDAP/LDAPS default port which is 389 or 636 depending on (SecureSocketLayer) and (TLS). + /// + /// 389 + [DefaultValue(0)] + public int Port { get; set; } + + /// + /// Perform secure operation. + /// + /// true + public bool SecureSocketLayer { get; set; } + + /// + /// Connection is protected by TLS. + /// + /// true + public bool TLS { get; set; } + + /// + /// User. + /// + /// Foo + public string User { get; set; } + + /// + /// Password. + /// + /// Bar123 + [PasswordPropertyText] + public string Password { get; set; } +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs new file mode 100644 index 0000000..e199ed0 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs @@ -0,0 +1,19 @@ +namespace Frends.LDAP.AddUserToGroups.Definitions; + +/// +/// Input parameters. +/// +public class Input +{ + /// + /// User's distinguished name (DN) + /// + /// CN=Tes Tuser,ou=users,dc=wimpi,dc=net + public string UserDistinguishedName { get; set; } + + /// + /// Group's distinguished name (DN) + /// + /// cn=admin,ou=roles,dc=wimpi,dc=net + public string GroupDistinguishedName { get; set; } +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Result.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Result.cs new file mode 100644 index 0000000..1632c8e --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Result.cs @@ -0,0 +1,39 @@ +namespace Frends.LDAP.AddUserToGroups.Definitions; + +/// +/// Task's result. +/// +public class Result +{ + /// + /// Update completed. + /// + /// true + public bool Success { get; private set; } + + /// + /// LDAP Error message. + /// + /// Entry Already Exists + public string Error { get; private set; } + + /// + /// User DN. + /// + /// CN=Tes Tuser,ou=users,dc=wimpi,dc=net + public string UserDistinguishedName { get; private set; } + + /// + /// Group DN. + /// + /// cn=admin,ou=roles,dc=wimpi,dc=net + public string GroupDistinguishedName { get; private set; } + + internal Result(bool success, string error, string userDistinguishedName, string groupDistinguishedName) + { + Success = success; + Error = error; + UserDistinguishedName = userDistinguishedName; + GroupDistinguishedName = groupDistinguishedName; + } +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.csproj b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.csproj new file mode 100644 index 0000000..f823688 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.csproj @@ -0,0 +1,27 @@ + + + + net6.0 + 1.0.0 + Frends + Frends + Frends + Frends + Frends + MIT + true + Add user to Active Directory groups. + https://frends.com/ + https://github.com/FrendsPlatform/Frends.LDAP + + + + + PreserveNewest + + + + + + + \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/FrendsTaskMetadata.json b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/FrendsTaskMetadata.json new file mode 100644 index 0000000..8a34f12 --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/FrendsTaskMetadata.json @@ -0,0 +1,7 @@ +{ + "Tasks": [ + { + "TaskMethod": "Frends.LDAP.AddUserToGroups.LDAP.AddUserToGroups" + } + ] +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/README.md b/Frends.LDAP.AddUserToGroups/README.md new file mode 100644 index 0000000..6f86b4b --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/README.md @@ -0,0 +1,30 @@ +# Frends.LDAP.AddUserToGroups +Frends LDAP task to add a user to Active Directory groups. + +[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) +[![Build](https://github.com/FrendsPlatform/Frends.LDAP/actions/workflows/AddUserToGroups_build_and_test_on_main.yml/badge.svg)](https://github.com/FrendsPlatform/Frends.LDAP/actions) +![MyGet](https://img.shields.io/myget/frends-tasks/v/Frends.LDAP.AddUserToGroups) +![Coverage](https://app-github-custom-badges.azurewebsites.net/Badge?key=FrendsPlatform/Frends.LDAP/Frends.LDAP.AddUserToGroups|main) + +# Installing + +You can install the Task via frends UI Task View or you can find the NuGet package from the following NuGet feed https://www.myget.org/F/frends-tasks/api/v2. + +## Building + + +Rebuild the project + +`dotnet build` + +Run tests + + Create a simple LDAP server to docker: + `docker run -d -it --rm -p 10389:10389 dwimberger/ldap-ad-it` + +`dotnet test` + + +Create a NuGet package + +`dotnet pack --configuration Release` \ No newline at end of file diff --git a/README.md b/README.md index b464c76..78fd22e 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Frends Task for Active Directory related operations. - [Frends.LDAP.DeleteUser](Frends.LDAP.DeleteUser/README.md) - [Frends.LDAP.SearchObjects](Frends.LDAP.SearchObjects/README.md) - [Frends.LDAP.UpdateUser](Frends.LDAP.UpdateUser/README.md) +- [Frends.LDAP.AddUserToGroups](Frends.LDAP.AddUserToGroups/README.md) # Contributing When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. From d441590ef14d346900a688ddaa1b9188d7365873 Mon Sep 17 00:00:00 2001 From: Teemu Tossavainen Date: Mon, 10 Oct 2022 12:47:46 +0300 Subject: [PATCH 2/4] init --- .../AddUserToGroups.cs | 5 ++++- .../Definitions/Enums.cs | 17 +++++++++++++++++ .../Definitions/Input.cs | 11 ++++++++++- Frends.LDAP.AddUserToGroups/README.md | 2 +- 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Enums.cs diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs index 02a6941..7292076 100644 --- a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs @@ -42,7 +42,10 @@ public static Result AddUserToGroups([PropertyTab] Input input, [PropertyTab] Co } catch (LdapException ex) { - return new Result(false, ex.Message, input.UserDistinguishedName, input.GroupDistinguishedName); + if (ex.Message.Equals("Attribute Or Value Exists") && input.UserExistsAction.Equals(UserExistsAction.Skip)) + return new Result(false, ex.Message, input.UserDistinguishedName, input.GroupDistinguishedName); + else + throw new LdapException($"AddUserToGroups LDAP error: {ex}"); } catch (Exception ex) { diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Enums.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Enums.cs new file mode 100644 index 0000000..0a4cdbc --- /dev/null +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Enums.cs @@ -0,0 +1,17 @@ +namespace Frends.LDAP.AddUserToGroups.Definitions; + +/// +/// Options if user is already in target group. +/// +public enum UserExistsAction +{ + /// + /// Throw an error. + /// + Throw, + + /// + /// Do nothing and add LDAP error message to the task's result. + /// + Skip +} \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs index e199ed0..0edca6b 100644 --- a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/Definitions/Input.cs @@ -1,4 +1,6 @@ -namespace Frends.LDAP.AddUserToGroups.Definitions; +using System.ComponentModel; + +namespace Frends.LDAP.AddUserToGroups.Definitions; /// /// Input parameters. @@ -16,4 +18,11 @@ public class Input /// /// cn=admin,ou=roles,dc=wimpi,dc=net public string GroupDistinguishedName { get; set; } + + /// + /// Handle user exists exception. + /// + /// UserExistsAction.Throw + [DefaultValue(UserExistsAction.Throw)] + public UserExistsAction UserExistsAction { get; set; } } \ No newline at end of file diff --git a/Frends.LDAP.AddUserToGroups/README.md b/Frends.LDAP.AddUserToGroups/README.md index 6f86b4b..0ab4cab 100644 --- a/Frends.LDAP.AddUserToGroups/README.md +++ b/Frends.LDAP.AddUserToGroups/README.md @@ -8,7 +8,7 @@ Frends LDAP task to add a user to Active Directory groups. # Installing -You can install the Task via frends UI Task View or you can find the NuGet package from the following NuGet feed https://www.myget.org/F/frends-tasks/api/v2. +You can install the Task via Frends UI Task View or you can find the NuGet package from the following NuGet feed https://www.myget.org/F/frends-tasks/api/v2. ## Building From 5e4d83b5db12e60755b6e060109b722053a650b4 Mon Sep 17 00:00:00 2001 From: Teemu Tossavainen Date: Mon, 10 Oct 2022 12:59:52 +0300 Subject: [PATCH 3/4] init --- .../UnitTests.cs | 84 ++++++------------- 1 file changed, 24 insertions(+), 60 deletions(-) diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs index e47e2bf..314ba55 100644 --- a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs @@ -6,17 +6,6 @@ namespace Frends.LDAP.AddUserToGroups.Tests; [TestClass] public class UnitTests { - // Azure AD. - /* - private readonly int _port = 389; - private readonly string? _path = "CN=Users,DC=FRENDSTest01,DC=net"; - private readonly string? _dn = "CN=Tes Tuser,CN=Users,DC=FRENDSTest01,DC=net"; - private readonly string? _groupDn = "CN=Users,CN=Builtin,DC=FRENDSTest01,DC=net"; - private readonly string? _host = Environment.GetEnvironmentVariable("HiQ_AzureADTest_Address"); - private readonly string? _user = Environment.GetEnvironmentVariable("HiQ_AzureADTest_User"); - private readonly string? _pw = Environment.GetEnvironmentVariable("HiQ_AzureADTest_Password"); - */ - /* LDAP server to docker. docker run -d -it --rm -p 10389:10389 dwimberger/ldap-ad-it @@ -26,36 +15,11 @@ LDAP server to docker. private readonly string? _user = "uid=admin,ou=system"; private readonly string? _pw = "secret"; private readonly string _path = "ou=users,dc=wimpi,dc=net"; - private readonly string? _dn = "CN=Tes Tuser,ou=users,dc=wimpi,dc=net"; private readonly string? _groupDn = "cn=admin,ou=roles,dc=wimpi,dc=net"; Input? input; Connection? connection; - [TestInitialize] - public void StartUp() - { - try - { - CreateTestUsers(); - } - catch (Exception) - { - } - } - - [TestCleanup] - public void CleanUp() - { - try - { - DeleteUser(); - } - catch (Exception) - { - } - } - [TestMethod] public void Update_HandleLDAPError_Test() { @@ -81,9 +45,13 @@ public void Update_HandleLDAPError_Test() [TestMethod] public void AddUserToGroups_Test() { + var tuser = "Tes Tuser" + Guid.NewGuid().ToString(); + var dn = $"CN={tuser},ou=users,dc=wimpi,dc=net"; + CreateTestUsers(tuser); + input = new() { - UserDistinguishedName = _dn, + UserDistinguishedName = dn, GroupDistinguishedName = _groupDn }; connection = new() @@ -100,31 +68,27 @@ public void AddUserToGroups_Test() Assert.IsTrue(result.Success.Equals(true)); } - public void CreateTestUsers() + public void CreateTestUsers(string tuser) { - LdapConnection conn = new(); - conn.Connect(_host, _port); - conn.Bind(_user, _pw); - - var attributeSet = new LdapAttributeSet(); - attributeSet.Add(new LdapAttribute("objectclass", "user")); - attributeSet.Add(new LdapAttribute("cn", "Tes Tuser")); - attributeSet.Add(new LdapAttribute("givenname", "Tes")); - attributeSet.Add(new LdapAttribute("sn", "Tuser")); + try + { + LdapConnection conn = new(); + conn.Connect(_host, _port); + conn.Bind(_user, _pw); - var entry = $"CN=Tes Tuser,{_path}"; - LdapEntry newEntry = new(entry, attributeSet); - conn.Add(newEntry); - conn.Disconnect(); - } + var attributeSet = new LdapAttributeSet(); + attributeSet.Add(new LdapAttribute("objectclass", "user")); + attributeSet.Add(new LdapAttribute("cn", tuser)); + attributeSet.Add(new LdapAttribute("givenname", "Tes")); + attributeSet.Add(new LdapAttribute("sn", tuser.Split(' ', 1))); - public void DeleteUser() - { - LdapConnection conn = new(); - conn.Connect(_host, _port); - conn.Bind(_user, _pw); - conn.Delete($"CN=Tes Tuser,{_path}"); - conn.Delete($"CN=Tes Tuser,{_path}"); - conn.Disconnect(); + var entry = $"CN={tuser},{_path}"; + LdapEntry newEntry = new(entry, attributeSet); + conn.Add(newEntry); + conn.Disconnect(); + } + catch (Exception) + { + } } } \ No newline at end of file From ab48df232fd41c44af03a754c88b594d2b1528ba Mon Sep 17 00:00:00 2001 From: Teemu Tossavainen Date: Mon, 10 Oct 2022 13:25:25 +0300 Subject: [PATCH 4/4] init --- .../Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs | 7 ++++--- .../Frends.LDAP.AddUserToGroups/AddUserToGroups.cs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs index 314ba55..e1fd56f 100644 --- a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups.Tests/UnitTests.cs @@ -26,7 +26,8 @@ public void Update_HandleLDAPError_Test() input = new() { UserDistinguishedName = "CN=Common Name,CN=Users,DC=Example,DC=Com", - GroupDistinguishedName = "CN=Admins,DC=Example,DC=Com" + GroupDistinguishedName = "CN=Admins,DC=Example,DC=Com", + UserExistsAction = UserExistsAction.Throw }; connection = new() { @@ -38,8 +39,8 @@ public void Update_HandleLDAPError_Test() TLS = false, }; - var result = LDAP.AddUserToGroups(input, connection); - Assert.IsTrue(result.Success.Equals(false) && result.Error.Contains("No Such Object")); + var ex = Assert.ThrowsException(() => LDAP.AddUserToGroups(input, connection)); + Assert.IsTrue(ex.Message.Contains("No Such Object")); } [TestMethod] diff --git a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs index 7292076..79d6b54 100644 --- a/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs +++ b/Frends.LDAP.AddUserToGroups/Frends.LDAP.AddUserToGroups/AddUserToGroups.cs @@ -45,7 +45,7 @@ public static Result AddUserToGroups([PropertyTab] Input input, [PropertyTab] Co if (ex.Message.Equals("Attribute Or Value Exists") && input.UserExistsAction.Equals(UserExistsAction.Skip)) return new Result(false, ex.Message, input.UserDistinguishedName, input.GroupDistinguishedName); else - throw new LdapException($"AddUserToGroups LDAP error: {ex}"); + throw new Exception($"AddUserToGroups LDAP error: {ex.Message}"); } catch (Exception ex) {