Skip to content

Commit

Permalink
Add validator for services with no auth trait
Browse files Browse the repository at this point in the history
Adds a validator that warns when there's a service shape that has
multiple authDefinition traits applied, but no auth trait. This
encourages the use of the auth trait so auth scheme priority is
being modeled explicitly. It also allows for tooling to look for
and use this validation event.

Documentation was also updated to explain that without the auth
trait, auth scheme ordering is alphabetical.

A test for the auth trait (auth-trait-must-target-service-schemes)
was updated to avoid getting the warning message from the new
validator.
  • Loading branch information
milesziemer committed Aug 16, 2023
1 parent 15586bd commit 6b5489b
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 1 deletion.
5 changes: 5 additions & 0 deletions docs/source-2.0/spec/authentication-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,11 @@ the ``auth`` trait, then the operation is expected to support each of the
service. Each entry in the ``auth`` trait is a shape ID that MUST refer to an
authentication scheme trait applied to the service in which it is bound.

.. note::
When a service has multiple authentication scheme traits applied and no
``auth`` trait, the ordering of authentication schemes is alphabetical
based on the absolute shape ID of each authentication scheme trait.

The following example defines all combinations in which ``auth`` can be applied
to services and operations:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.smithy.model.validation.validators;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.ServiceIndex;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.traits.AuthTrait;
import software.amazon.smithy.model.validation.AbstractValidator;
import software.amazon.smithy.model.validation.ValidationEvent;

/**
* Validates that services with multiple @authDefinition traits applied also
* have an @auth trait applied.
*/
public class ServiceWithNoAuthTraitValidator extends AbstractValidator {

@Override
public List<ValidationEvent> validate(Model model) {
List<ValidationEvent> events = new ArrayList<>();
ServiceIndex index = ServiceIndex.of(model);

List<ServiceShape> services = model.getServiceShapes().stream()
.filter(serviceShape -> !serviceShape.hasTrait(AuthTrait.ID))
.filter(serviceShape -> index.getAuthSchemes(serviceShape).size() > 1)
.collect(Collectors.toList());

for (ServiceShape service : services) {
events.add(warning(service, "This service uses multiple authentication schemes but does not have "
+ "the `@auth` trait applied. The `@auth` trait defines a priority ordering "
+ "of auth schemes for a client to use. Without it, the ordering of auth "
+ "schemes is alphabetical based on the absolute shape ID of the auth "
+ "schemes."));

}
return events;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ software.amazon.smithy.model.validation.validators.ResourceIdentifierBindingVali
software.amazon.smithy.model.validation.validators.ResourceIdentifierValidator
software.amazon.smithy.model.validation.validators.ResourceLifecycleValidator
software.amazon.smithy.model.validation.validators.ResourceOperationInputOutputValidator
software.amazon.smithy.model.validation.validators.ServiceWithNoAuthTraitValidator
software.amazon.smithy.model.validation.validators.ServiceValidator
software.amazon.smithy.model.validation.validators.SetValidator
software.amazon.smithy.model.validation.validators.ShapeIdConflictValidator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
],
"traits": {
"smithy.api#httpBasicAuth": {},
"smithy.api#httpDigestAuth": {}
"smithy.api#httpDigestAuth": {},
"smithy.api#auth": [
"smithy.api#httpDigestAuth",
"smithy.api#httpBasicAuth"
]
}
},
"ns.foo#ValidOperation": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[WARNING] smithy.example#FooService: This service uses multiple authentication schemes but is not annotated with the @auth trait. The @auth trait defines a priority ordering of auth schemes for a client to use. Without it, the ordering of auth schemes is alphabetical based on the absolute shape id of the auth schemes. | ServiceWithNoAuthTrait
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
$version: "2"

namespace smithy.example

// Service shape with multiple auth schemes and no auth trait should cause warning
@httpBasicAuth
@httpDigestAuth
@httpBearerAuth
service FooService {
version: "2023-08-15"
operations: [GetFoo]
}

operation GetFoo {
output: GetFooOutput
}

structure GetFooOutput {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$version: "2"

namespace smithy.example

// Service shape with one auth schemes and no auth trait should NOT cause warning
@httpBasicAuth
service FooService {
version: "2023-08-15"
operations: [GetFoo]
}

operation GetFoo {
output: GetFooOutput
}

structure GetFooOutput {}

0 comments on commit 6b5489b

Please sign in to comment.