Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ad domain services #404

Merged
merged 17 commits into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ With the generic resources:

The following is a list of static resources.

- [azure_active_directory_domain_service](docs/resources/azure_active_directory_domain_service.md)
- [azure_active_directory_domain_services](docs/resources/azure_active_directory_domain_services.md)
- [azure_aks_cluster](docs/resources/azure_aks_cluster.md)
- [azure_aks_clusters](docs/resources/azure_aks_clusters.md)
- [azure_api_management](docs/resources/azure_api_management.md)
Expand Down
91 changes: 91 additions & 0 deletions docs/resources/azure_active_directory_domain_service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: About the azure_active_directory_domain_service Resource
platform: azure
---

# azure_active_directory_domain_service

Use the `azure_active_directory_domain_service` InSpec audit resource to test properties of an Azure Active Directory service within a tenant.

## Azure REST API version, endpoint and http client parameters

This resource interacts with api versions supported by the resource provider.
The `api_version` can be defined as a resource parameter.
If not provided, the latest stable version will be used.
For more information, refer to [`azure_graph_generic_resource`](azure_graph_generic_resource.md).

Unless defined, `azure_cloud` global endpoint, and default values for the http client will be used.
For more information, refer to the resource pack [README](../../README.md).

## Availability

### Installation

This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure).
For an example `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).

## Syntax

```ruby
describe azure_active_directory_domain_service(id: 'example.com') do
it { should exist }
end
```
## Parameters

Either one of the following parameters is mandatory.

| Name | Description | Example |
|--------------------|-------------|---------|
| id | Domain ID | `example.com` |

## Properties

| Property | Description |
|-------------------------------|-------------------------------------------------------------------------------|
| id | The fully qualified name of the domain. Key, immutable, not nullable, unique. |
| authenticationType | Indicates the configured authentication type for the domain.The value is either `Managed` or `Federated`. |
| availabilityStatus | This property is always `null` except when the verify action is used. |
| isAdminManaged | The value of the property is `false` if the DNS record management of the domain has been delegated to Microsoft 365. |
| isDefault | `true` if this is the default domain that is used for user creation. There is only one default domain per company. Not nullable |
| isInitial | `true` if this is the initial domain created by Microsoft Online Services (companyname.onmicrosoft.com). There is only one initial domain per company. |
| isRoot | `true` if the domain is a verified root domain. Otherwise, `false` if the domain is a subdomain or unverified. |
| isVerified | `true` if the domain has completed domain ownership verification. |
| passwordNotificationWindowInDays| Specifies the number of days before a user receives notification that their password will expire. If the property is not set, a default value of 14 days will be used. |
| passwordValidityPeriodInDays | Specifies the length of time that a password is valid before it must be changed. If the property is not set, a default value of 90 days will be used. |
| supportedServices | The capabilities assigned to the domain. |
| state | Status of asynchronous operations scheduled for the domain. |

## Examples

### Test If an Active Directory Domain is Referenced with a Valid ID

```ruby
describe azure_active_directory_domain_service(id: 'example.com') do
it { should exist }
end
```

### Test If an Active Directory Domain is Referenced with an Invalid ID

```ruby
describe azure_active_directory_domain_service(id: 'example.com') do
it { should_not exist }
end
```

## Matchers

This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [Universal Matchers page](https://www.inspec.io/docs/reference/matchers/).

### exists

```ruby
describe azure_active_directory_domain_service(id: 'example.onmicrosoft.com') do
it { should exist }
end
```
## Azure Permissions

Graph resources require specific privileges granted to your service principal.
Please refer to the [Microsoft Documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications#updating-an-application) for information on how to grant these permissions to your application.
111 changes: 111 additions & 0 deletions docs/resources/azure_active_directory_domain_services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
title: About the azure_active_directory_domain_services Resource
platform: azure
---

# azure_active_directory_domain_services
Use the `azure_active_directory_domain_services` InSpec audit resource to test properties of some or all Azure Active Directory domains within a tenant.

## Azure REST API version, endpoint and http client parameters

This resource interacts with api versions supported by the resource provider.
The `api_version` can be defined as a resource parameter.
If not provided, the latest stable version will be used.
For more information, refer to [`azure_graph_generic_resources`](azure_graph_generic_resources.md).

Unless defined, `azure_cloud` global endpoint, and default values for the http client will be used.
For more information, refer to the resource pack [README](../../README.md).

## Availability

### Installation

This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure).
For an example `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).

## Syntax

An `azure_active_directory_domain_services` resource block returns all Azure Active Directory domains contained within the configured tenant and then tests that group of domains.

```ruby
describe azure_active_directory_domain_services do
#...
end
```

## Parameters

The following parameters can be passed for targeting specific domains.

| Name | Description | Example |
|-------------------|-------------------------------------------------------------|-------------------------------------|
| filter | A hash containing the filtering options and their values. The `starts_with_` operator can be used for fuzzy string matching. Parameter names are in snake case. | `{ starts_with_given_name: 'J', starts_with_department: 'Core', country: 'United Kingdom', given_name: John}` |
| filter_free_text | [OData](https://www.odata.org/getting-started/basic-tutorial/) query string in double quotes, `"`. Property names are in camel case, refer to [Microsoft's query parameters documentation](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) for more information. | `"startswith(displayName,'J') and surname eq 'Doe'"` or `"userType eq 'Guest'"` |

It is advised to use these parameters to narrow down the targeted resources at the server side, Azure Graph API, for a more efficient test.

## Properties

| Property | Description | Filter Criteria<superscript>*</superscript> |
|-----------------------|------------------------------------------------------------------|---------------------------------------------|
| ids | A list of fully qualified names of the domain. | `id` |
| authentication_types | A list of the configured authentication types for the domain. | `authenticationType` |
| availability_statuses | A list of domain entities when verify action is set. | `availabilityStatus` |
| is_admin_manageds | A list of admin managed configuration. | `isAdminManaged` |
| is_defaults | A list of flags to indicate if they are default domains. | `isDefault` |
| is_initials | A list of flags to indicate if they are initial domains created by Microsoft Online Services.| `isInitial` |
| is_roots | A list of flags to indicate if they are verified root domains. | `isRoot` |
| is_verifieds | A list of flags to indicate if the domains have completed domain ownership verification.| `isVerified` |
| password_notification_window_in_days | A list of password notification window days. | `passwordNotificationWindowInDays` |
| password_validity_period_in_days | A list of password validity periods in days. | `passwordValidityPeriodInDays` |
| supported_services | A list of capabilities assigned to the domain. | `supportedServices` |
| states | A list of asynchronous operations scheduled. | `state` |

<superscript>*</superscript> For information on how to use filter criteria on plural resources refer to [FilterTable usage](https://github.com/inspec/inspec/blob/master/dev-docs/filtertable-usage.md).

## Examples

The following examples show how to use this InSpec audit resource.

### Check domains with some filtering parameters applied at server side using `filter`

```ruby
describe azure_active_directory_domain_services(filter: {authenticationType: "authenticationType-value"}) do
it { should exist }
end
```

### Check domains with some filtering parameters applied at server side using `filter_free_text`

```ruby
describe azure_active_directory_domain_services(filter_free_text: "startswith(authenticationType,'authenticationType-value')") do
it { should exist }
end
```

### Ensure there are supported services using client-side filtering

```ruby
describe azure_active_directory_domain_services.supportedServices do
it { should_not exist }
end
```

## Matchers

This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [Universal Matchers page](https://www.inspec.io/docs/reference/matchers/).

### exists

The control will pass if the filter returns at least one result. Use `should_not` if you expect zero matches.

```ruby
describe azure_active_directory_domain_services do
it { should_not exist }
end
```

## Azure Permissions

Graph resources require specific privileges granted to your service principal.
Please refer to the [Microsoft Documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications#updating-an-application) for information on how to grant these permissions to your application.
27 changes: 27 additions & 0 deletions libraries/azure_active_directory_domain_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'azure_graph_generic_resource'

class AzureActiveDirectoryDomainService < AzureGraphGenericResource
name 'azure_active_directory_domain_service'
desc 'Verifies settings for an Azure AD Domain Service'
example <<-EXAMPLE
describe azure_active_directory_domain_service(id: 'M365x214355.onmicrosoft.com') do
it { should exist }
end
EXAMPLE

def initialize(opts = {})
raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)

opts[:resource] = 'domains'
opts[:resource_identifiers] = %i(id)
super(opts, true)
end

def exists?
!failed_resource?
end

def to_s
super(AzureGraphUser)
end
end
21 changes: 21 additions & 0 deletions libraries/azure_active_directory_domain_services.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'azure_graph_generic_resources'

class AzureActiveDirectoryDomainServices < AzureGraphGenericResources
name 'azure_active_directory_domain_services'
desc 'Verifies settings for all Azure Active Directory Domain Services'
example <<-EXAMPLE
describe azure_active_directory_domain_services do
it { should exist }
end
EXAMPLE

def initialize(opts = {})
raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)

opts[:resource] = 'domains'
opts[:select] = %w{id authenticationType availabilityStatus isAdminManaged isDefault isInitial isRoot isVerified supportedServices passwordNotificationWindowInDays passwordValidityPeriodInDays state}
super(opts, true)

self.class.populate_filter_table(:table, @table_schema)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
control 'azure_active_directory_domain_service' do

azure_active_directory_domain_services.ids.each do |domain_service_id|
describe azure_active_directory_domain_service(id: domain_service_id) do
it { should exist }
its('isVerified') { should eq true }
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
control 'azure_active_directory_domain_services' do

describe azure_active_directory_domain_services do
it { should exist }
end
end
24 changes: 24 additions & 0 deletions test/unit/resources/azure_active_directory_domain_service_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require_relative 'helper'
require 'azure_active_directory_domain_service'

class AzureActiveDirectoryDomainServiceConstructorTest < Minitest::Test
# Generic resource requires a parameter.
def test_empty_params_not_ok
assert_raises(ArgumentError) { AzureActiveDirectoryDomainService.new }
end

def test_not_allowed_parameter
assert_raises(ArgumentError) { AzureActiveDirectoryDomainService.new(resource: 'domains', id: 'some_id', fake: 'random') }
end

def test_filter_not_allowed
assert_raises(ArgumentError) { AzureActiveDirectoryDomainService.new(resource: 'domains', id: 'some_id', filter: 'random') }
end

def test_resource_identifier_is_a_list
assert_raises(ArgumentError) do
AzureActiveDirectoryDomainService.new(resource: 'domains', id: 'some_id',
resource_identifier: 'random')
end
end
end
19 changes: 19 additions & 0 deletions test/unit/resources/azure_active_directory_domain_services_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require_relative 'helper'
require 'azure_active_directory_domain_services'

class AzureActiveDirectoryDomainServicesConstructorTest < Minitest::Test
def test_not_allowed_parameter
assert_raises(ArgumentError) { AzureActiveDirectoryDomainServices.new(resource: 'domains', fake: 'rubbish') }
end

def test_id_not_allowed
assert_raises(ArgumentError) { AzureActiveDirectoryDomainServices.new(resource: 'domains', id: 'some_id') }
end

def test_filter_filter_free_text_together_not_allowed
assert_raises(ArgumentError) do
AzureActiveDirectoryDomainServices.new(resource: 'domains',
filter: { name: 'some_id' }, filter_free_text: %w{some_filter})
end
end
end