Skip to content

Commit 12ba5b2

Browse files
authored
Use sttp monad error (#336)
* remove redundant toTry conversion * use sttp MonadError * add migration guide * silent mima
1 parent 509a4af commit 12ba5b2

File tree

9 files changed

+65
-49
lines changed

9 files changed

+65
-49
lines changed

build.sbt

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,21 @@ def compilerPlugins =
7373
libraryDependencies ++= (if (scalaVersion.value.startsWith("3")) Seq()
7474
else Seq(compilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")))
7575

76-
val mimaSettings =
77-
mimaPreviousArtifacts := {
78-
val currentVersion = version.value
79-
lazy val onlyPatchChanged =
80-
previousStableVersion.value.flatMap(CrossVersion.partialVersion) == CrossVersion.partialVersion(currentVersion)
81-
lazy val isRcOrMilestone = currentVersion.contains("-M") || currentVersion.contains("-RC")
82-
if (onlyPatchChanged && !isRcOrMilestone) {
83-
previousStableVersion.value.map(organization.value %% moduleName.value % _).toSet
84-
} else {
85-
Set.empty
86-
}
87-
}
76+
val mimaSettings = {
77+
// revert the commit that made this change after releasing a new version
78+
//mimaPreviousArtifacts := {
79+
// val currentVersion = version.value
80+
// lazy val onlyPatchChanged =
81+
// previousStableVersion.value.flatMap(CrossVersion.partialVersion) == CrossVersion.partialVersion(currentVersion)
82+
// lazy val isRcOrMilestone = currentVersion.contains("-M") || currentVersion.contains("-RC")
83+
// if (onlyPatchChanged && !isRcOrMilestone) {
84+
// previousStableVersion.value.map(organization.value %% moduleName.value % _).toSet
85+
// } else {
86+
// Set.empty
87+
// }
88+
//}
89+
mimaPreviousArtifacts := Set.empty
90+
}
8891

8992
// Workaround for https://github.com/typelevel/sbt-tpolecat/issues/102
9093
val jsSettings = scalacOptions ++= (if (scalaVersion.value.startsWith("3")) Seq("-scalajs") else Seq())

docs/migrating.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ description: Migrations
77

88
Some releases introduce breaking changes. This page aims to list those and provide migration guide.
99

10+
## [v0.16.0](https://github.com/ocadotechnology/sttp-oauth2/releases/tag/v0.16.0)
11+
12+
Minor change [#336](https://github.com/ocadotechnology/sttp-oauth2/pull/336) removed implicit parameter
13+
of `cats.MonadThrow` in some methods. As long as your code just uses these methods (doesn't override or mock
14+
interfaces), you have to only solve warnings suggesting that there are unused parameters. Otherwise,
15+
remove `: MonadError` from inherited implementations.
16+
17+
Affected classes: `PasswordGrant`, `PasswordGrantProvider`, `SttpOauth2ClientCredentialsBackend`, `UserInfoProvider`
18+
1019
## [v0.15.0](https://github.com/ocadotechnology/sttp-oauth2/releases/tag/v0.15.0)
1120

1221
### Breaking change in authorization code grant

oauth2/shared/src/main/scala/com/ocadotechnology/sttp/oauth2/AccessTokenProvider.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ object AccessTokenProvider {
3636
override def requestToken(scope: Option[Scope]): F[ClientCredentialsToken.AccessTokenResponse] =
3737
ClientCredentials
3838
.requestToken(tokenUrl, clientId, clientSecret, scope)(backend)
39-
.map(_.leftMap(OAuth2Exception.apply).toTry)
40-
.flatMap(backend.responseMonad.fromTry)
39+
.map(_.leftMap(OAuth2Exception.apply))
40+
.flatMap(_.fold(F.error, F.unit))
4141

4242
}
4343

oauth2/shared/src/main/scala/com/ocadotechnology/sttp/oauth2/AuthorizationCode.scala

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ object AuthorizationCode {
4545
)(
4646
backend: SttpBackend[F, Any]
4747
): F[RT] = {
48-
implicit val ME: MonadError[F] = backend.responseMonad
48+
implicit val F: MonadError[F] = backend.responseMonad
4949
backend
5050
.send {
5151
basicRequest
@@ -54,15 +54,8 @@ object AuthorizationCode {
5454
.response(asString)
5555
.header(HeaderNames.Accept, "application/json")
5656
}
57-
.flatMap { response =>
58-
ME.fromTry(
59-
response
60-
.body
61-
.leftMap(new RuntimeException(_))
62-
.flatMap(decode[RT])
63-
.toTry
64-
)
65-
}
57+
.map(_.body.leftMap(new RuntimeException(_)).flatMap(decode[RT]))
58+
.flatMap(_.fold(F.error, F.unit))
6659
}
6760

6861
private def tokenRequestParams(authCode: String, redirectUri: String, clientId: String, clientSecret: String) =
@@ -91,8 +84,8 @@ object AuthorizationCode {
9184
.body(refreshTokenRequestParams(refreshToken, clientId, clientSecret.value, scopeOverride.toRequestMap))
9285
.response(asString)
9386
}
94-
.map(_.body.leftMap(new RuntimeException(_)).flatMap(decode[RT]).toTry)
95-
.flatMap(backend.responseMonad.fromTry)
87+
.map(_.body.leftMap(new RuntimeException(_)).flatMap(decode[RT]))
88+
.flatMap(_.fold(F.error, F.unit))
9689
}
9790

9891
private def refreshTokenRequestParams(refreshToken: String, clientId: String, clientSecret: String, scopeOverride: Map[String, String]) =

oauth2/shared/src/main/scala/com/ocadotechnology/sttp/oauth2/PasswordGrant.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.ocadotechnology.sttp.oauth2
22

3-
import cats.Functor
4-
import common._
3+
import com.ocadotechnology.sttp.oauth2.common._
54
import eu.timepit.refined.types.string.NonEmptyString
65
import sttp.client3._
76
import sttp.model.Uri
8-
import cats.syntax.all._
7+
import sttp.monad.MonadError
8+
import sttp.monad.syntax._
99

1010
object PasswordGrant {
1111

@@ -22,15 +22,16 @@ object PasswordGrant {
2222

2323
}
2424

25-
def requestToken[F[_]: Functor](
25+
def requestToken[F[_]](
2626
tokenUri: Uri,
2727
user: User,
2828
clientId: NonEmptyString,
2929
clientSecret: Secret[String],
3030
scope: Scope
3131
)(
3232
backend: SttpBackend[F, Any]
33-
): F[OAuth2Token.Response] =
33+
): F[OAuth2Token.Response] = {
34+
implicit val F: MonadError[F] = backend.responseMonad
3435
backend
3536
.send {
3637
basicRequest
@@ -39,6 +40,7 @@ object PasswordGrant {
3940
.response(OAuth2Token.response)
4041
}
4142
.map(_.body)
43+
}
4244

4345
private def requestTokenParams(clientId: NonEmptyString, user: User, clientSecret: Secret[String], scope: Scope) =
4446
Map(
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.ocadotechnology.sttp.oauth2
22

3-
import cats.MonadThrow
4-
import common._
3+
import cats.syntax.all._
54
import com.ocadotechnology.sttp.oauth2.PasswordGrant.User
5+
import com.ocadotechnology.sttp.oauth2.common._
66
import eu.timepit.refined.types.string.NonEmptyString
77
import sttp.client3.SttpBackend
88
import sttp.model.Uri
9-
import cats.syntax.all._
9+
import sttp.monad.MonadError
10+
import sttp.monad.syntax._
1011

1112
trait PasswordGrantProvider[F[_]] {
1213
def requestToken(user: User, scope: Scope): F[ExtendedOAuth2TokenResponse]
@@ -16,14 +17,18 @@ object PasswordGrantProvider {
1617

1718
def apply[F[_]](implicit ev: PasswordGrantProvider[F]): PasswordGrantProvider[F] = ev
1819

19-
def apply[F[_]: MonadThrow](
20+
def apply[F[_]](
2021
tokenUrl: Uri,
2122
clientId: NonEmptyString,
2223
clientSecret: Secret[String]
2324
)(
2425
backend: SttpBackend[F, Any]
2526
): PasswordGrantProvider[F] = { (user: User, scope: Scope) =>
26-
PasswordGrant.requestToken(tokenUrl, user, clientId, clientSecret, scope)(backend).map(_.leftMap(OAuth2Exception.apply)).rethrow
27+
implicit val F: MonadError[F] = backend.responseMonad
28+
PasswordGrant
29+
.requestToken(tokenUrl, user, clientId, clientSecret, scope)(backend)
30+
.map(_.leftMap(OAuth2Exception.apply))
31+
.flatMap(_.fold(F.error, F.unit))
2732
}
2833

2934
}

oauth2/shared/src/main/scala/com/ocadotechnology/sttp/oauth2/SttpOauth2ClientCredentialsBackend.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
package com.ocadotechnology.sttp.oauth2
22

3-
import cats.Monad
4-
import cats.implicits._
53
import com.ocadotechnology.sttp.oauth2.common.Scope
64
import eu.timepit.refined.types.string.NonEmptyString
75
import sttp.capabilities.Effect
86
import sttp.client3._
97
import sttp.model.Uri
8+
import sttp.monad.MonadError
9+
import sttp.monad.syntax._
1010

1111
/** SttpBackend, that adds auth bearer headers to every request.
1212
*/
13-
final class SttpOauth2ClientCredentialsBackend[F[_]: Monad, P] private (
13+
final class SttpOauth2ClientCredentialsBackend[F[_], P] private (
1414
delegate: SttpBackend[F, P],
1515
accessTokenProvider: AccessTokenProvider[F],
1616
scope: Option[common.Scope]
1717
) extends DelegateSttpBackend(delegate) {
18+
implicit val F: MonadError[F] = delegate.responseMonad
1819

1920
override def send[T, R >: P with Effect[F]](request: Request[T, R]): F[Response[T]] = for {
2021
token <- accessTokenProvider.requestToken(scope)
@@ -25,7 +26,7 @@ final class SttpOauth2ClientCredentialsBackend[F[_]: Monad, P] private (
2526

2627
object SttpOauth2ClientCredentialsBackend {
2728

28-
def apply[F[_]: Monad, P](
29+
def apply[F[_], P](
2930
tokenUrl: Uri,
3031
clientId: NonEmptyString,
3132
clientSecret: Secret[String]
@@ -38,7 +39,7 @@ object SttpOauth2ClientCredentialsBackend {
3839
SttpOauth2ClientCredentialsBackend(accessTokenProvider)(scope)(backend)
3940
}
4041

41-
def apply[F[_]: Monad, P](
42+
def apply[F[_], P](
4243
accessTokenProvider: AccessTokenProvider[F]
4344
)(
4445
scope: Option[Scope]

oauth2/shared/src/main/scala/com/ocadotechnology/sttp/oauth2/TokenIntrospection.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ object TokenIntrospection {
3737
override def introspect(token: Secret[String]): F[Introspection.TokenIntrospectionResponse] =
3838
ClientCredentials
3939
.introspectToken(tokenIntrospectionUrl, clientId, clientSecret, token)(backend)
40-
.map(_.leftMap(OAuth2Exception.apply).toTry)
41-
.flatMap(backend.responseMonad.fromTry)
40+
.map(_.leftMap(OAuth2Exception.apply))
41+
.flatMap(_.fold(F.error, F.unit))
4242

4343
}
4444

oauth2/shared/src/main/scala/com/ocadotechnology/sttp/oauth2/UserInfoProvider.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.ocadotechnology.sttp.oauth2
22

3-
import cats.MonadThrow
43
import cats.syntax.all._
54
import eu.timepit.refined.api.Refined
65
import eu.timepit.refined.string.Url
76
import io.circe.parser.decode
87
import sttp.client3._
98
import sttp.model.Uri
9+
import sttp.monad.MonadError
10+
import sttp.monad.syntax._
1011

1112
trait UserInfoProvider[F[_]] {
1213
def userInfo(accessToken: String): F[UserInfo]
@@ -15,12 +16,13 @@ trait UserInfoProvider[F[_]] {
1516
object UserInfoProvider {
1617
def apply[F[_]](implicit ev: UserInfoProvider[F]): UserInfoProvider[F] = ev
1718

18-
private def requestUserInfo[F[_]: MonadThrow](
19+
private def requestUserInfo[F[_]](
1920
baseUrl: Uri,
2021
accessToken: String
2122
)(
2223
backend: SttpBackend[F, Any]
23-
): F[UserInfo] =
24+
): F[UserInfo] = {
25+
implicit val F: MonadError[F] = backend.responseMonad
2426
backend
2527
.send {
2628
basicRequest
@@ -29,18 +31,19 @@ object UserInfoProvider {
2931
.response(asString)
3032
}
3133
.map(_.body.leftMap(new RuntimeException(_)).flatMap(decode[UserInfo]))
32-
.rethrow
34+
.flatMap(_.fold(F.error, F.unit))
35+
}
3336

3437
// TODO - add some description on what is expected of baseUrl
35-
def apply[F[_]: MonadThrow](
38+
def apply[F[_]](
3639
baseUrl: Uri
3740
)(
3841
backend: SttpBackend[F, Any]
3942
): UserInfoProvider[F] =
4043
(accessToken: String) => requestUserInfo(baseUrl, accessToken)(backend)
4144

4245
// TODO - add some description on what is expected of baseUrl
43-
def apply[F[_]: MonadThrow](
46+
def apply[F[_]](
4447
baseUrl: String Refined Url
4548
)(
4649
backend: SttpBackend[F, Any]

0 commit comments

Comments
 (0)