1 /*
2  *  Make.org Core API
3  *  Copyright (C) 2018 Make.org
4  *
5  * This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  *
18  */
19 
20 package org.make.api.technical.auth
21 
22 import org.make.api.extensions.MakeSettingsComponent
23 import org.make.api.technical.IdGeneratorComponent
24 import org.make.core.auth.{Client, ClientId}
25 import org.make.core.technical.Pagination
26 import org.make.core.user.{CustomRole, UserId}
27 import scalaoauth2.provider.{InvalidClient, InvalidRequest, OAuthError}
28 
29 import scala.concurrent.ExecutionContext.Implicits.global
30 import scala.concurrent.Future
31 
32 trait DefaultClientServiceComponent extends ClientServiceComponent {
33   this: PersistentClientServiceComponent with IdGeneratorComponent with MakeSettingsComponent =>
34 
35   override lazy val clientService: ClientService = new DefaultClientService
36 
37   class DefaultClientService extends ClientService {
38 
39     override def getClient(clientId: ClientId): Future[Option[Client]] = {
40       persistentClientService.get(clientId)
41     }
42 
43     override def createClient(
44       name: String,
45       allowedGrantTypes: Seq[String],
46       secret: Option[String],
47       scope: Option[String],
48       redirectUri: Option[String],
49       defaultUserId: Option[UserId],
50       roles: Seq[CustomRole],
51       tokenExpirationSeconds: Int,
52       refreshExpirationSeconds: Int,
53       reconnectExpirationSeconds: Int
54     ): Future[Client] = {
55       persistentClientService.persist(
56         Client(
57           clientId = idGenerator.nextClientId(),
58           name = name,
59           allowedGrantTypes = allowedGrantTypes,
60           secret = secret,
61           scope = scope,
62           redirectUri = redirectUri,
63           defaultUserId = defaultUserId,
64           roles = roles,
65           tokenExpirationSeconds = tokenExpirationSeconds,
66           refreshExpirationSeconds = refreshExpirationSeconds,
67           reconnectExpirationSeconds = reconnectExpirationSeconds
68         )
69       )
70     }
71 
72     override def search(
73       offset: Pagination.Offset,
74       end: Option[Pagination.End],
75       name: Option[String]
76     ): Future[Seq[Client]] =
77       persistentClientService.search(offset = offset, end = end, name = name)
78 
79     override def updateClient(
80       clientId: ClientId,
81       name: String,
82       allowedGrantTypes: Seq[String],
83       secret: Option[String],
84       scope: Option[String],
85       redirectUri: Option[String],
86       defaultUserId: Option[UserId],
87       roles: Seq[CustomRole],
88       tokenExpirationSeconds: Int,
89       refreshExpirationSeconds: Int,
90       reconnectExpirationSeconds: Int
91     ): Future[Option[Client]] = {
92       getClient(clientId).flatMap {
93         case Some(client) =>
94           persistentClientService
95             .update(
96               client.copy(
97                 name = name,
98                 allowedGrantTypes = allowedGrantTypes,
99                 secret = secret,
100                 scope = scope,
101                 redirectUri = redirectUri,
102                 defaultUserId = defaultUserId,
103                 roles = roles,
104                 tokenExpirationSeconds = tokenExpirationSeconds,
105                 refreshExpirationSeconds = refreshExpirationSeconds,
106                 reconnectExpirationSeconds = reconnectExpirationSeconds
107               )
108             )
109         case None => Future.successful(None)
110       }
111     }
112 
113     override def count(name: Option[String]): Future[Int] = {
114       persistentClientService.count(name = name)
115     }
116 
117     override def getClient(clientId: ClientId, secret: Option[String]): Future[Either[OAuthError, Client]] = {
118       getClient(clientId).map {
119         case Some(client) =>
120           if (client.secret == secret) {
121             Right(client)
122           } else {
123             Left(new InvalidClient(s"Credentials mismatch for client ${clientId.value}."))
124           }
125 
126         case None => Left(new InvalidClient(s"Client ${clientId.value} was not found."))
127       }
128     }
129 
130     override def getDefaultClient(): Future[Either[OAuthError, Client]] = {
131       getClient(ClientId(makeSettings.Authentication.defaultClientId)).map {
132         case Some(client) => Right(client)
133         case None         => Left(new InvalidRequest("Default client was not found, check your configuration."))
134       }
135     }
136   }
137 }
Line Stmt Id Pos Tree Symbol Tests Code
40 22647 1562 - 1599 Apply org.make.api.technical.auth.PersistentClientService.get org.make.api.technical.auth.clientservicetest DefaultClientServiceComponent.this.persistentClientService.get(clientId)
55 24529 1999 - 2529 Apply org.make.api.technical.auth.PersistentClientService.persist org.make.api.technical.auth.clientservicetest DefaultClientServiceComponent.this.persistentClientService.persist({ <artifact> val x$1: org.make.core.auth.ClientId = DefaultClientServiceComponent.this.idGenerator.nextClientId(); <artifact> val x$2: String = name; <artifact> val x$3: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = allowedGrantTypes; <artifact> val x$4: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = secret; <artifact> val x$5: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = scope; <artifact> val x$6: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = redirectUri; <artifact> val x$7: Option[org.make.core.user.UserId] @scala.reflect.internal.annotations.uncheckedBounds = defaultUserId; <artifact> val x$8: Seq[org.make.core.user.CustomRole] @scala.reflect.internal.annotations.uncheckedBounds = roles; <artifact> val x$9: Int = tokenExpirationSeconds; <artifact> val x$10: Int = refreshExpirationSeconds; <artifact> val x$11: Int = reconnectExpirationSeconds; <artifact> val x$12: Option[java.time.ZonedDateTime] @scala.reflect.internal.annotations.uncheckedBounds = org.make.core.auth.Client.apply$default$7; <artifact> val x$13: Option[java.time.ZonedDateTime] @scala.reflect.internal.annotations.uncheckedBounds = org.make.core.auth.Client.apply$default$8; org.make.core.auth.Client.apply(x$1, x$2, x$3, x$4, x$5, x$6, x$12, x$13, x$7, x$8, x$9, x$10, x$11) })
56 23108 2040 - 2040 Select org.make.core.auth.Client.apply$default$8 org.make.api.technical.auth.clientservicetest org.make.core.auth.Client.apply$default$8
56 26870 2040 - 2521 Apply org.make.core.auth.Client.apply org.make.api.technical.auth.clientservicetest org.make.core.auth.Client.apply(x$1, x$2, x$3, x$4, x$5, x$6, x$12, x$13, x$7, x$8, x$9, x$10, x$11)
56 24440 2040 - 2040 Select org.make.core.auth.Client.apply$default$7 org.make.api.technical.auth.clientservicetest org.make.core.auth.Client.apply$default$7
57 26406 2069 - 2095 Apply org.make.core.technical.IdGenerator.nextClientId org.make.api.technical.auth.clientservicetest DefaultClientServiceComponent.this.idGenerator.nextClientId()
77 22260 2692 - 2763 Apply org.make.api.technical.auth.PersistentClientService.search org.make.api.technical.auth.clientservicetest DefaultClientServiceComponent.this.persistentClientService.search(offset, end, name)
92 22486 3191 - 3889 ApplyToImplicitArgs scala.concurrent.Future.flatMap org.make.api.technical.auth.clientservicetest DefaultClientService.this.getClient(clientId).flatMap[Option[org.make.core.auth.Client]](((x0$1: Option[org.make.core.auth.Client]) => x0$1 match { case (value: org.make.core.auth.Client): Some[org.make.core.auth.Client]((client @ _)) => DefaultClientServiceComponent.this.persistentClientService.update({ <artifact> val x$1: String = name; <artifact> val x$2: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = allowedGrantTypes; <artifact> val x$3: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = secret; <artifact> val x$4: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = scope; <artifact> val x$5: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = redirectUri; <artifact> val x$6: Option[org.make.core.user.UserId] @scala.reflect.internal.annotations.uncheckedBounds = defaultUserId; <artifact> val x$7: Seq[org.make.core.user.CustomRole] @scala.reflect.internal.annotations.uncheckedBounds = roles; <artifact> val x$8: Int = tokenExpirationSeconds; <artifact> val x$9: Int = refreshExpirationSeconds; <artifact> val x$10: Int = reconnectExpirationSeconds; <artifact> val x$11: org.make.core.auth.ClientId = client.copy$default$1; <artifact> val x$12: Option[java.time.ZonedDateTime] @scala.reflect.internal.annotations.uncheckedBounds = client.copy$default$7; <artifact> val x$13: Option[java.time.ZonedDateTime] @scala.reflect.internal.annotations.uncheckedBounds = client.copy$default$8; client.copy(x$11, x$1, x$2, x$3, x$4, x$5, x$12, x$13, x$6, x$7, x$8, x$9, x$10) }) case scala.None => scala.concurrent.Future.successful[None.type](scala.None) }))(scala.concurrent.ExecutionContext.Implicits.global)
92 24837 3219 - 3219 Select scala.concurrent.ExecutionContext.Implicits.global org.make.api.technical.auth.clientservicetest scala.concurrent.ExecutionContext.Implicits.global
95 24453 3260 - 3836 Apply org.make.api.technical.auth.PersistentClientService.update DefaultClientServiceComponent.this.persistentClientService.update({ <artifact> val x$1: String = name; <artifact> val x$2: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = allowedGrantTypes; <artifact> val x$3: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = secret; <artifact> val x$4: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = scope; <artifact> val x$5: Option[String] @scala.reflect.internal.annotations.uncheckedBounds = redirectUri; <artifact> val x$6: Option[org.make.core.user.UserId] @scala.reflect.internal.annotations.uncheckedBounds = defaultUserId; <artifact> val x$7: Seq[org.make.core.user.CustomRole] @scala.reflect.internal.annotations.uncheckedBounds = roles; <artifact> val x$8: Int = tokenExpirationSeconds; <artifact> val x$9: Int = refreshExpirationSeconds; <artifact> val x$10: Int = reconnectExpirationSeconds; <artifact> val x$11: org.make.core.auth.ClientId = client.copy$default$1; <artifact> val x$12: Option[java.time.ZonedDateTime] @scala.reflect.internal.annotations.uncheckedBounds = client.copy$default$7; <artifact> val x$13: Option[java.time.ZonedDateTime] @scala.reflect.internal.annotations.uncheckedBounds = client.copy$default$8; client.copy(x$11, x$1, x$2, x$3, x$4, x$5, x$12, x$13, x$6, x$7, x$8, x$9, x$10) })
96 26415 3319 - 3822 Apply org.make.core.auth.Client.copy client.copy(x$11, x$1, x$2, x$3, x$4, x$5, x$12, x$13, x$6, x$7, x$8, x$9, x$10)
96 26333 3326 - 3326 Select org.make.core.auth.Client.copy$default$1 client.copy$default$1
96 24993 3326 - 3326 Select org.make.core.auth.Client.copy$default$7 client.copy$default$7
96 22962 3326 - 3326 Select org.make.core.auth.Client.copy$default$8 client.copy$default$8
109 23251 3876 - 3880 Select scala.None scala.None
109 27096 3858 - 3881 Apply scala.concurrent.Future.successful scala.concurrent.Future.successful[None.type](scala.None)
114 26341 3965 - 4007 Apply org.make.api.technical.auth.PersistentClientService.count DefaultClientServiceComponent.this.persistentClientService.count(name)
118 24980 4132 - 4473 ApplyToImplicitArgs scala.concurrent.Future.map org.make.api.technical.auth.clientservicetest DefaultClientService.this.getClient(clientId).map[Either[scalaoauth2.provider.OAuthError,org.make.core.auth.Client]](((x0$1: Option[org.make.core.auth.Client]) => x0$1 match { case (value: org.make.core.auth.Client): Some[org.make.core.auth.Client]((client @ _)) => if (client.secret.==(secret)) scala.`package`.Right.apply[Nothing, org.make.core.auth.Client](client) else scala.`package`.Left.apply[scalaoauth2.provider.InvalidClient, Nothing](new scalaoauth2.provider.InvalidClient(("Credentials mismatch for client ".+(clientId.value).+("."): String))) case scala.None => scala.`package`.Left.apply[scalaoauth2.provider.InvalidClient, Nothing](new scalaoauth2.provider.InvalidClient(("Client ".+(clientId.value).+(" was not found."): String))) }))(scala.concurrent.ExecutionContext.Implicits.global)
118 26273 4156 - 4156 Select scala.concurrent.ExecutionContext.Implicits.global org.make.api.technical.auth.clientservicetest scala.concurrent.ExecutionContext.Implicits.global
120 25139 4201 - 4224 Apply java.lang.Object.== client.secret.==(secret)
121 22970 4240 - 4253 Apply scala.util.Right.apply scala.`package`.Right.apply[Nothing, org.make.core.auth.Client](client)
121 26715 4240 - 4253 Block scala.util.Right.apply scala.`package`.Right.apply[Nothing, org.make.core.auth.Client](client)
123 24372 4290 - 4362 Apply scalaoauth2.provider.InvalidClient.<init> new scalaoauth2.provider.InvalidClient(("Credentials mismatch for client ".+(clientId.value).+("."): String))
123 26854 4285 - 4363 Block scala.util.Left.apply scala.`package`.Left.apply[scalaoauth2.provider.InvalidClient, Nothing](new scalaoauth2.provider.InvalidClient(("Credentials mismatch for client ".+(clientId.value).+("."): String)))
123 23265 4285 - 4363 Apply scala.util.Left.apply scala.`package`.Left.apply[scalaoauth2.provider.InvalidClient, Nothing](new scalaoauth2.provider.InvalidClient(("Credentials mismatch for client ".+(clientId.value).+("."): String)))
126 24844 4403 - 4464 Apply scalaoauth2.provider.InvalidClient.<init> new scalaoauth2.provider.InvalidClient(("Client ".+(clientId.value).+(" was not found."): String))
126 22498 4398 - 4465 Apply scala.util.Left.apply scala.`package`.Left.apply[scalaoauth2.provider.InvalidClient, Nothing](new scalaoauth2.provider.InvalidClient(("Client ".+(clientId.value).+(" was not found."): String)))
131 22426 4563 - 4797 ApplyToImplicitArgs scala.concurrent.Future.map DefaultClientService.this.getClient(org.make.core.auth.ClientId.apply(DefaultClientServiceComponent.this.makeSettings.Authentication.defaultClientId)).map[Either[scalaoauth2.provider.OAuthError,org.make.core.auth.Client]](((x0$1: Option[org.make.core.auth.Client]) => x0$1 match { case (value: org.make.core.auth.Client): Some[org.make.core.auth.Client]((client @ _)) => scala.`package`.Right.apply[Nothing, org.make.core.auth.Client](client) case scala.None => scala.`package`.Left.apply[scalaoauth2.provider.InvalidRequest, Nothing](new scalaoauth2.provider.InvalidRequest("Default client was not found, check your configuration.")) }))(scala.concurrent.ExecutionContext.Implicits.global)
131 24605 4632 - 4632 Select scala.concurrent.ExecutionContext.Implicits.global scala.concurrent.ExecutionContext.Implicits.global
131 22726 4582 - 4625 Select org.make.api.extensions.MakeSettings.Authentication.defaultClientId DefaultClientServiceComponent.this.makeSettings.Authentication.defaultClientId
131 26724 4573 - 4626 Apply org.make.core.auth.ClientId.apply org.make.core.auth.ClientId.apply(DefaultClientServiceComponent.this.makeSettings.Authentication.defaultClientId)
132 24385 4663 - 4676 Apply scala.util.Right.apply scala.`package`.Right.apply[Nothing, org.make.core.auth.Client](client)
133 26867 4706 - 4789 Apply scala.util.Left.apply scala.`package`.Left.apply[scalaoauth2.provider.InvalidRequest, Nothing](new scalaoauth2.provider.InvalidRequest("Default client was not found, check your configuration."))
133 28133 4711 - 4788 Apply scalaoauth2.provider.InvalidRequest.<init> new scalaoauth2.provider.InvalidRequest("Default client was not found, check your configuration.")