Skip to content

Commit

Permalink
Update withSecurity endpoint definitions, add examples, remove duplic…
Browse files Browse the repository at this point in the history
…ated 403 definitions
  • Loading branch information
philemone committed Oct 15, 2024
1 parent bf4588e commit 625a435
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 395 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import pl.touk.nussknacker.ui.security.api.SecurityError.{
ImpersonationNotSupportedError,
InsufficientPermission
}
import sttp.model.StatusCode.{Forbidden, NotFound, NotImplemented, Unauthorized}
import sttp.model.StatusCode.{Forbidden, NotImplemented, Unauthorized}
import sttp.tapir.EndpointIO.Example
import sttp.tapir._

Expand All @@ -29,7 +29,6 @@ trait BaseEndpointDefinitions {

object BaseEndpointDefinitions {

type EndpointError[ERROR] = Either[SecurityError, ERROR]
type SecuredEndpoint[INPUT, BUSINESS_ERROR, OUTPUT, -R] =
Endpoint[AuthCredentials, INPUT, Either[BUSINESS_ERROR, SecurityError], OUTPUT, R]

Expand Down Expand Up @@ -67,37 +66,20 @@ object BaseEndpointDefinitions {
)
)
),
oneOfVariantFromMatchType(
NotFound,
plainBody[ImpersonatedUserDataNotFoundError.type]
.description("Identity provided in the Nu-Impersonate-User-Identity header did not match any user")
.example(
Example.of(
summary = Some("No impersonated user's data found for provided identity"),
value = ImpersonatedUserDataNotFoundError
)
)
),
oneOfVariantFromMatchType(
Forbidden,
plainBody[ImpersonationMissingPermissionError.type]
.example(
Example.of(
summary = Some("Authorization failed, user does not have permission to impersonate"),
value = ImpersonationMissingPermissionError
oneOfBody[SecurityError](
plainBody[SecurityError]
.examples(
List(
Example.of(name = Some("InsufficientPermission"), value = InsufficientPermission),
Example
.of(name = Some("ImpersonationMissingPermission"), value = ImpersonationMissingPermissionError),
Example.of(name = Some("ImpersonatedUserDataNotFound"), value = ImpersonatedUserDataNotFoundError)
)
)
)
)
),
oneOfVariantFromMatchType(
Forbidden,
plainBody[InsufficientPermission.type]
.example(
Example.of(
summary = Some("Authorization failed"),
value = InsufficientPermission
)
)
)
)
)
}
Expand All @@ -106,36 +88,16 @@ object BaseEndpointDefinitions {

private object Codecs {

implicit val authenticationErrorCodec: Codec[String, CannotAuthenticateUser.type, CodecFormat.TextPlain] = {
Codec.string.map(
Mapping.from[String, CannotAuthenticateUser.type](_ => CannotAuthenticateUser)(_ =>
"The supplied authentication is invalid"
)
)
}

implicit val authorizationErrorCodec: Codec[String, InsufficientPermission.type, CodecFormat.TextPlain] = {
Codec.string.map(
Mapping.from[String, InsufficientPermission.type](_ => InsufficientPermission)(_ =>
"The supplied authentication is not authorized to access this resource"
)
)
}

implicit val impersonationPermissionErrorCodec
: Codec[String, ImpersonationMissingPermissionError.type, CodecFormat.TextPlain] = {
implicit val authorizationErrorCodec: Codec[String, SecurityError, CodecFormat.TextPlain] = {
Codec.string.map(
Mapping.from[String, ImpersonationMissingPermissionError.type](_ => ImpersonationMissingPermissionError)(_ =>
ImpersonationMissingPermissionError.errorMessage
)
Mapping.from[String, SecurityError](_ => InsufficientPermission)(s => s.errorMessage)
)
}

implicit val impersonatedDataNotFoundErrorCodec
: Codec[String, ImpersonatedUserDataNotFoundError.type, CodecFormat.TextPlain] = {
implicit val authenticationErrorCodec: Codec[String, CannotAuthenticateUser.type, CodecFormat.TextPlain] = {
Codec.string.map(
Mapping.from[String, ImpersonatedUserDataNotFoundError.type](_ => ImpersonatedUserDataNotFoundError)(_ =>
ImpersonatedUserDataNotFoundError.errorMessage
Mapping.from[String, CannotAuthenticateUser.type](_ => CannotAuthenticateUser)(_ =>
"The supplied authentication is invalid"
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,6 @@ object TestingApiHttpService {
)
)

val noProcessingTypeExample: EndpointOutput.OneOfVariant[NoProcessingType] =
oneOfVariantFromMatchType(
NotFound,
plainBody[NoProcessingType]
.example(
Example.of(
summary = Some("ProcessingType type: {processingType} not found"),
value = NoProcessingType("'processingType'")
)
)
)

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class TestingApiEndpoints(auth: EndpointInput[AuthCredentials]) extends BaseEndp
)
.errorOut(
oneOf[TestingError](
noScenarioExample // TODO
noScenarioExample
)
)
.withSecurity(auth)
Expand Down Expand Up @@ -205,7 +205,7 @@ class TestingApiEndpoints(auth: EndpointInput[AuthCredentials]) extends BaseEndp
.errorOut(
oneOf[TestingError](
testDataGenerationErrorExample,
noScenarioExample // TODO
noScenarioExample
)
)
.withSecurity(auth)
Expand Down
Loading

0 comments on commit 625a435

Please sign in to comment.