Compare commits

...

5 Commits

Author SHA1 Message Date
739c8cb9b0 stop raising build error on lint warnings for now (#49) 2020-10-02 16:06:22 +02:00
5983c760b5 disable error on lint warnings 2020-10-02 15:52:59 +02:00
045adbf647 Modernize Build Pipeline (#48) 2020-10-02 15:48:58 +02:00
b6e791f709 adds security section (#47)
- add security section
- update content
- fix github deployment state
- update about page based on readme.md
2020-01-23 13:06:16 +01:00
d0a6457d37 Adds Social Logo (#46)
* add social logo
* add social logo in Readme
2019-05-10 10:12:26 +02:00
10 changed files with 204 additions and 16 deletions

32
.drone.yml Normal file
View File

@ -0,0 +1,32 @@
---
kind: pipeline
type: docker
name: Linux_PWSH7_Build
platform:
os: linux
arch: amd64
steps:
- name: Environments
image: mcr.microsoft.com/powershell:latest
commands:
- pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1' -Verbose; Invoke-ShowEnv -Verbose}"
- pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1' -Verbose; Invoke-InstallDependencies -Verbose}"
- name: LintTests
image: mcr.microsoft.com/powershell:latest
commands:
- pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-InstallDependencies}"
- pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-Linter}"
- name: UnitTests
image: mcr.microsoft.com/powershell:latest
commands:
- pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-InstallDependencies}"
- pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-UnitTests}"
- name: coverage
image: plugins/codecov
settings:
token:
from_secret: CodeCovToken
files:
- coverage.xml

View File

@ -1,6 +1,7 @@
[![AppVeyor branch](https://img.shields.io/appveyor/ci/OCram85/PSCredentialStore/master.svg?style=plastic "Master Branch Build Status")](https://ci.appveyor.com/project/OCram85/pscredentialstore/branch/master)
[![AppVeyor tests branch](https://img.shields.io/appveyor/tests/OCram85/PSCredentialStore/master.svg?style=plastic "Pester Tests Results")](https://ci.appveyor.com/project/OCram85/pscredentialstore/branch/master/tests)
[![Coveralls github](https://img.shields.io/coveralls/github/OCram85/PSCredentialStore.svg?style=plastic "Coveralls.io Coverage Report")](https://coveralls.io/github/OCram85/PSCredentialStore?branch=master)
[![codecov](https://codecov.io/gh/OCram85/PSCredentialStore/branch/master/graph/badge.svg)](https://codecov.io/gh/OCram85/PSCredentialStore)
[![PowerShell Gallery](https://img.shields.io/powershellgallery/v/PSCredentialStore.svg?style=plastic "PowershellGallery Published Version")](https://www.powershellgallery.com/packages/PSCredentialStore)
[![PowerShell Gallery](https://img.shields.io/powershellgallery/vpre/PSCredentialStore.svg?label=latest%20preview&style=plastic "PowershellGallery Latest Preview Version")](https://www.powershellgallery.com/packages/PSCredentialStore)
[![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/PSCredentialStore.svg?style=plastic "PowershellGallery Downloads")](https://www.powershellgallery.com/packages/PSCredentialStore)
@ -8,6 +9,8 @@
![forthebadge](http://forthebadge.com/images/badges/built-with-love.svg)
![forthebadge](http://forthebadge.com/images/badges/for-you.svg)
![social-logo](/assets/social-logo.png)
:key: General
=======
@ -33,6 +36,38 @@ You can find the [reference](/docs/PSCredentialStore.md) in the /docs/ path as w
- PowerShell >= `5.1`
- .NET Framework >= `4.6` or .NET Core >= `1.0`
:bomb: About Security
============
>This section explains some security topics and the the design decisions we made to balance the usage and security needs.
To be able to delegate `PSCredentials` objects we can't exclusively rely on the `SecureString` cmdlets. You can't
decrypt and reuse such credentials from a different user account or even machine. This is caused by automatically
generated encryption key which, is used create a `Secure String` based encrypted string.
In order to delegate a password, while still using the underlying security framework, we have to provide a custom
encryption key. This leads to the fact, that everyone who has access to the key could encrypt or decrypt your data.
So we decided to use the public and private keys from valid certificates as part of the custom encryption keys to encrypt your data.
This means clearly: Everyone who has access to the `CredentialStore` needs also access to the certificate file to work with it.
Keep in mind you need to secure the access with your NTFS file permissions to avoid unwanted usage. Another option is
to import the certificate into your certification vaults of you operating system. In this case you can grand the
permission to the certificates itself.
Here is s brief hierarchy description of the certificate location: *(First match wins)*
| CredentialStore Type | Certificate Location |
| -------------------- | ---------------------- |
| Private | `CurrentUser`\\`My` |
| Shared (Windows) | `CurrentUser`\\`My` |
| | `LocalMachine`\\`Root` |
| Shared (Linux) | `LocalMachine`\\`My` |
| | `LocalMachine`\\`Root` |
:hammer_and_wrench: Installation
============

View File

@ -1,6 +1,8 @@
# pre release version:
version: 1.0.{build}
#cache:
#branches:
# only:
# - master
@ -9,9 +11,7 @@ version: 1.0.{build}
skip_tags: true
#image: WMF 5
# Test ne build image:
image: Visual Studio 2017
image: Visual Studio 2019
# Install pester module and init the Appveyor support.
@ -28,6 +28,8 @@ environment:
secure: 835qfZIkC9mE7QhkYfOZVAdR8rZhPvxG8BO4CbeaelRQOhlqmaSr8G1DWRJzZ/bS
CoverallsToken:
secure: eTjWqHL48MBr8wp1rSgLrXHdtpfDV/uClacP3svlWJfCvn/zVokpuaMnWM5RoyIY
CodeCovToken:
secure: LJOvamWIlVORDE7120KcmWVkHxOFYBSN99linyICXXmXLtYm81K/31YeMGiPlgTm
build: false
@ -61,13 +63,12 @@ deploy:
secure: M+bBX5/nKdJB0eViP7xtrLVTwf3vGDUA9N2MMprZp2i+9ZR3CBVcJnSzJWUmalhB
artifact: PSCredentialStore.zip # upload all NuGet packages to release assets
draft: false
prerelease: true
prerelease: false
on:
branch: master # build release on master branch changes
after_deploy:
- ps: Invoke-AppVeyorPSGallery -OnBranch 'master'
# Pause build until `lock` on desktop is deleted.
#on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

BIN
assets/colorscheme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
assets/social-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -26,6 +26,36 @@ For more details read the [about_PSCredentialStore](/docs/about_PSCredentialStor
- PowerShell >= `5.1`
- .NET Framework >= `4.6` or .NET Core >= `1.0`
## About Security
>This section explains some security topics and the the design decisions we made to balance the usage and security needs.
To be able to delegate `PSCredentials` objects we can't exclusively rely on the `SecureString` cmdlets. You can't
decrypt and reuse such credentials from a different user account or even machine. This is caused by automatically
generated encryption key which, is used create a `Secure String` based encrypted string.
In order to delegate a password, while still using the underlying security framework, we have to provide a custom
encryption key. This leads to the fact, that everyone who has access to the key could encrypt or decrypt your data.
So we decided to use the public and private keys from valid certificates as part of the custom encryption keys to encrypt your data.
This means clearly: Everyone who has access to the `CredentialStore` needs also access to the certificate file to work with it.
Keep in mind you need to secure the access with your NTFS file permissions to avoid unwanted usage. Another option is
to import the certificate into your certification vaults of you operating system. In this case you can grand the
permission to the certificates itself.
Here is s brief hierarchy description of the certificate location: *(First match wins)*
| CredentialStore Type | Certificate Location |
| -------------------- | ---------------------- |
| Private | `CurrentUser`\\`My` |
| Shared (Windows) | `CurrentUser`\\`My` |
| | `LocalMachine`\\`Root` |
| Shared (Linux) | `LocalMachine`\\`My` |
| | `LocalMachine`\\`Root` |
## Installation
## PowerShellGallery.com (Recommended Way)
@ -56,7 +86,7 @@ New-CredentialStore
# Private credential store with certificate store usage
New-CredentialStore -UseCertStore
# Shared credential rtore
# Shared credential store
New-CredentialStore -Shared
#Shared credential store in custom Location

View File

@ -19,7 +19,7 @@
CompanyName = ''
# Copyright statement for this module
Copyright = '(c) 2019 OCram85. All rights reserved.'
Copyright = '(c) 2020 OCram85. All rights reserved.'
# Description of the functionality provided by this module
Description = 'A simple credential manager to store and reuse multiple credential objects.'

View File

@ -16,13 +16,19 @@ Function Invoke-InstallDependencies() {
Process {
Try {
Write-Host 'Available PS modules are:' -ForegroundColor Green -BackgroundColor Black
Get-Module -ListAvailable -Name Pester | Format-Table | Out-String
Get-PackageProvider -ListAvailable
Install-PackageProvider -Name NuGet -RequiredVersion '2.8.5.208' -Force -Verbose
Import-PackageProvider -Name NuGet -RequiredVersion '2.8.5.208' -Force
Install-Module -Name 'Pester' -Scope CurrentUser -RequiredVersion '4.4.2' -Force -SkipPublisherCheck -AllowClobber
Install-Module -Name 'posh-git' -Scope CurrentUser -RequiredVersion '1.0.0-beta2' -Force -SkipPublisherCheck -AllowClobber -AllowPrerelease
Install-Module -Name 'PSCoverage' -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber -RequiredVersion '1.0.78'
Import-Module -Name 'Pester', 'posh-git' , 'PSCoverage'
Write-Host 'Installing build deps...' -ForegroundColor Red -BackgroundColor Black
Install-Module -Name 'Pester' -Scope CurrentUser -RequiredVersion '4.10.1' -Force -SkipPublisherCheck -AllowClobber -Verbose
Install-Module -Name 'posh-git' -Scope CurrentUser -RequiredVersion '0.7.3' -Force -SkipPublisherCheck -AllowClobber
Install-Module -Name 'PSCoverage' -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber -RequiredVersion '1.2.108' -Verbose
Import-Module -Name 'posh-git'
Remove-Module -Name 'Pester' -Force -ErrorAction SilentlyContinue
Import-Module -Name 'Pester' -RequiredVersion '4.10.1' -Verbose -Force
Import-Module -Name 'PSCoverage' -RequiredVersion '1.2.108' -Verbose -Force
}
Catch {
$MsgParams = @{
@ -33,7 +39,8 @@ Function Invoke-InstallDependencies() {
Add-AppveyorMessage @MsgParams
Throw $MsgParams.Message
}
Write-Host 'Loaded PS modules are:' -ForegroundColor Green -BackgroundColor Black
Get-Module -Name Pester | Format-Table | Out-String
}
}
Function Invoke-AppVeyorBumpVersion() {
@ -42,7 +49,7 @@ Function Invoke-AppVeyorBumpVersion() {
Write-Host "Listing Env Vars for debugging:" -ForegroundColor Black -BackgroundColor Yellow
# Filter Results to prevent exposing secure vars.
Get-ChildItem -Path "Env:*" | Where-Object { $_.name -notmatch "(NuGetToken|CoverallsToken)"} | Sort-Object -Property Name | Format-Table
Get-ChildItem -Path "Env:*" | Where-Object { $_.name -notmatch "(NuGetToken|CoverallsToken|CodeCovToken)" } | Sort-Object -Property Name | Format-Table
Try {
$ModManifest = Get-Content -Path (".\src\{0}.psd1" -f $CALLSIGN)
@ -112,6 +119,7 @@ Function Invoke-AppVeyorTests() {
Write-Warning -Message ('Could not find file: {0} !' -f $File.FullName)
}
}
Write-Host '===== Preload done. =====' -ForegroundColor Black -BackgroundColor Yellow
}
catch {
$_.Exception.Message | Write-Error
@ -121,7 +129,7 @@ Function Invoke-AppVeyorTests() {
#$testresults = Invoke-Pester -Path ( Get-ChildItem -Path ".\tests\*.Tests.ps1" -Recurse | Sort-Object -Property Name ) -ExcludeTag 'Disabled' -PassThru
$srcFiles = Get-ChildItem -Path ".\src\*.ps1" -Recurse | Sort-Object -Property 'Name' | Select-Object -ExpandProperty 'FullName'
$testFiles = Get-ChildItem -Path ".\tests\*.Tests.ps1" -Recurse | Sort-Object -Property 'Name' | Select-Object -ExpandProperty 'FullName'
$TestResults = Invoke-Pester -Path $testFiles -CodeCoverage $srcFiles -PassThru
$TestResults = Invoke-Pester -Path $testFiles -CodeCoverage $srcFiles -PassThru -CodeCoverageOutputFile ".\coverage.xml" -CodeCoverageOutputFileEncoding ascii -CodeCoverageOutputFileFormat JaCoCo
ForEach ($Item in $TestResults.TestResult) {
Switch ($Item.Result) {
"Passed" {
@ -193,6 +201,7 @@ Function Invoke-CoverageReport() {
Publish-CoverageReport -CoverageReport $CoverageReport
}
Function Invoke-AppVeyorPSGallery() {
[CmdletBinding()]
Param(

81
tools/DroneIO.psm1 Normal file
View File

@ -0,0 +1,81 @@
$Global:ProgressPreference = 'SilentlyContinue'
function Invoke-ShowEnv() {
[CmdletBinding()]
param()
process {
Get-ChildItem -Path 'Env:' | Format-Table | Out-String
}
}
function Invoke-InstallDependencies() {
[CmdletBinding()]
[OutputType()]
param()
process {
try {
Install-Module -Name 'PSScriptAnalyzer' -Scope CurrentUser -RequiredVersion '1.19.1' -Force -SkipPublisherCheck -AllowClobber -Verbose:$VerbosePreference -ErrorAction 'Stop'
Install-Module -Name 'Pester' -Scope CurrentUser -RequiredVersion '4.10.1' -Force -SkipPublisherCheck -AllowClobber -Verbose:$VerbosePreference -ErrorAction 'Stop'
Install-Module -Name 'posh-git' -Scope CurrentUser -RequiredVersion '0.7.3' -Force -SkipPublisherCheck -AllowClobber -Verbose:$VerbosePreference -ErrorAction 'Stop'
Install-Module -Name 'PSCoverage' -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber -RequiredVersion '1.2.108' -Verbose:$VerbosePreference -ErrorAction 'Stop'
}
catch {
$ExceParams = @{
Exception = [System.Exception]::new(
'Could not install required build dependencies!',
$PSItem.Exception
)
ErrorAction = 'Stop'
}
Write-Error @ExceParams
}
}
}
function Invoke-Linter () {
[CmdletBinding()]
param()
process {
Invoke-ScriptAnalyzer -Path './src/' -Recurse
}
}
function Invoke-UnitTests {
[CmdletBinding()]
Param()
process {
try {
Write-Host '===== Preload internal private functions =====' -ForegroundColor Black -BackgroundColor Yellow
$Privates = Get-ChildItem -Path (Join-Path -Path $Env:DRONE_WORKSPACE -ChildPath '/src/Private/*') -Include "*.ps1" -Recurse -ErrorAction Stop
foreach ($File in $Privates) {
if (Test-Path -Path $File.FullName) {
. $File.FullName
Write-Verbose -Message ('Private function dot-sourced: {0}' -f $File.FullName) -Verbose
}
else {
Write-Warning -Message ('Could not find file: {0} !' -f $File.FullName)
}
}
}
catch {
$_.Exception.Message | Write-Error
throw 'Could not load required private functions!'
}
Write-Host '===== Running Pester =====' -ForegroundColor Black -BackgroundColor Yellow
$srcFiles = Get-ChildItem -Path "./src/*.ps1" -Recurse | Sort-Object -Property 'Name' | Select-Object -ExpandProperty 'FullName'
$TestFiles = Get-ChildItem -Path (Join-Path -Path '.' -ChildPath './tests/*.Tests.ps1') -Recurse | Sort-Object -Property Name
$TestResults = Invoke-Pester -Path $testFiles -CodeCoverage $srcFiles -PassThru -CodeCoverageOutputFile "./coverage.xml" -CodeCoverageOutputFileEncoding ascii -CodeCoverageOutputFileFormat JaCoCo
if ($TestResults.FailedCount -gt 0) {
throw ('{0} tests failed!' -f $TestResults.FailedCount)
}
}
}