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

Feat/#728 #756

Merged
merged 16 commits into from
Oct 9, 2024
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
33 changes: 22 additions & 11 deletions daikoku/app/controllers/ApiController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,7 @@ class ApiController(
apiKey = data.apiKey,
plan = data.plan,
createdAt = DateTime.now(),
validUntil = None,
team = data.team,
api = data.api,
by = ctx.user.id,
Expand Down Expand Up @@ -1749,7 +1750,8 @@ class ApiController(
customMaxPerDay = (body \ "customMaxPerDay").asOpt[Long],
customMaxPerMonth = (body \ "customMaxPerMonth").asOpt[Long],
customReadOnly = (body \ "customReadOnly").asOpt[Boolean],
adminCustomName = (body \ "adminCustomName").asOpt[String]
adminCustomName = (body \ "adminCustomName").asOpt[String],
validUntil = (body \ "validUntil").asOpt(DateTimeFormat),
)
result <-
EitherT(apiService.updateSubscription(ctx.tenant, subToSave, plan))
Expand Down Expand Up @@ -1781,6 +1783,7 @@ class ApiController(

def subscriptionToJson(
api: Api,
apiTeam: Team,
plan: UsagePlan,
sub: ApiSubscription,
parentSub: Option[ApiSubscription]
Expand All @@ -1797,8 +1800,9 @@ class ApiController(
Json.obj("planName" -> name) ++
Json.obj("apiName" -> api.name) ++
Json.obj("_humanReadableId" -> api.humanReadableId) ++
Json.obj("parentUp" -> false)

Json.obj("parentUp" -> false) ++
Json.obj("apiLink" -> s"/${apiTeam.humanReadableId}/${api.humanReadableId}/${api.currentVersion.value}/description") ++
Json.obj("planLink" -> s"/${apiTeam.humanReadableId}/${api.humanReadableId}/${api.currentVersion.value}/pricing")
sub.parent match {
case None => FastFuture.successful(r)
case Some(parentId) =>
Expand Down Expand Up @@ -1871,14 +1875,21 @@ class ApiController(
case None =>
FastFuture.successful(Json.obj()) //FIXME
case Some(plan) =>
subscriptionToJson(
api = api,
plan = plan,
sub = sub,
parentSub = sub.parent.flatMap(p =>
subscriptions.find(s => s.id == p)
)
)
env.dataStore.teamRepo.forTenant(ctx.tenant)
.findByIdNotDeleted(api.team)
.flatMap {
case Some(team) => subscriptionToJson(
api = api,
apiTeam = team,
plan = plan,
sub = sub,
parentSub = sub.parent.flatMap(p =>
subscriptions.find(s => s.id == p)
)
)
case None => FastFuture.successful(Json.obj()) //FIXME
}

}

case None => FastFuture.successful(Json.obj())
Expand Down
3 changes: 2 additions & 1 deletion daikoku/app/controllers/OtoroshiSettingsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,8 @@ class OtoroshiSettingsController(
.flatMap(_.asOpt[Map[String, String]])
.getOrElse(Map.empty[String, String]),
rotation = None,
readOnly = readOnlyOpt.getOrElse(false)
readOnly = readOnlyOpt.getOrElse(false),
validUntil = None,
)
}

Expand Down
5 changes: 3 additions & 2 deletions daikoku/app/domain/SchemaDefinition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ object SchemaDefinition {
ApiKeyRestrictionsType,
resolve = _.value.restrictions
)
)
),
)

lazy val AuthorizedEntitiesType = deriveObjectType[
Expand Down Expand Up @@ -2110,6 +2110,7 @@ object SchemaDefinition {
)
),
Field("createdAt", DateTimeUnitype, resolve = _.value.createdAt),
Field("validUntil", OptionType(DateTimeUnitype), resolve = _.value.validUntil),
Field(
"team",
OptionType(TeamObjectType),
Expand Down Expand Up @@ -3567,7 +3568,7 @@ object SchemaDefinition {
),
ReplaceField(
"validUntil",
Field("validUntil", DateTimeUnitype, resolve = _.value.validUntil)
Field("validUntil", OptionType(DateTimeUnitype), resolve = _.value.validUntil)
)
)
lazy val TranslationType =
Expand Down
10 changes: 8 additions & 2 deletions daikoku/app/domain/apikeyEntities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ case class ApikeyCustomization(
metadata: JsObject = play.api.libs.json.Json.obj(),
customMetadata: Seq[CustomMetadata] = Seq.empty,
tags: JsArray = play.api.libs.json.Json.arr(),
restrictions: ApiKeyRestrictions = ApiKeyRestrictions()
restrictions: ApiKeyRestrictions = ApiKeyRestrictions(),
) extends CanJson[ApikeyCustomization] {
def asJson: JsValue = json.ApikeyCustomizationFormat.writes(this)
}
Expand Down Expand Up @@ -59,6 +59,7 @@ case class ApiSubscription(
apiKey: OtoroshiApiKey, // TODO: add the actual plan at the time of the subscription
plan: UsagePlanId,
createdAt: DateTime,
validUntil: Option[DateTime] = None,
team: TeamId,
api: ApiId,
by: UserId,
Expand Down Expand Up @@ -108,6 +109,10 @@ case class ApiSubscription(
"team" -> json.TeamIdFormat.writes(team),
"api" -> json.ApiIdFormat.writes(api),
"createdAt" -> json.DateTimeFormat.writes(createdAt),
"validUntil" -> validUntil
.map(json.DateTimeFormat.writes)
.getOrElse(JsNull)
.as[JsValue],
"customName" -> customName
.map(id => JsString(id))
.getOrElse(JsNull)
Expand Down Expand Up @@ -135,7 +140,8 @@ case class ActualOtoroshiApiKey(
tags: Set[String] = Set.empty[String],
metadata: Map[String, String] = Map.empty[String, String],
restrictions: ApiKeyRestrictions = ApiKeyRestrictions(),
rotation: Option[ApiKeyRotation]
rotation: Option[ApiKeyRotation],
validUntil : Option[Long] = None
) extends CanJson[OtoroshiApiKey] {
override def asJson: JsValue = json.ActualOtoroshiApiKeyFormat.writes(this)
def asOtoroshiApiKey: OtoroshiApiKey =
Expand Down
16 changes: 12 additions & 4 deletions daikoku/app/domain/json.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1662,7 +1662,7 @@ object json {
.asOpt(SeqCustomMetadataFormat)
.getOrElse(Seq.empty),
tags = (json \ "tags").asOpt[JsArray].getOrElse(Json.arr()),
restrictions = (json \ "restrictions").as(ApiKeyRestrictionsFormat)
restrictions = (json \ "restrictions").as(ApiKeyRestrictionsFormat),
)
)
} recover {
Expand All @@ -1679,7 +1679,7 @@ object json {
o.customMetadata.map(CustomMetadataFormat.writes)
),
"tags" -> o.tags,
"restrictions" -> o.restrictions.asJson
"restrictions" -> o.restrictions.asJson,
)
}
val ApiKeyRestrictionsFormat = new Format[ApiKeyRestrictions] {
Expand Down Expand Up @@ -2732,6 +2732,7 @@ object json {
team = (json \ "team").as(TeamIdFormat),
api = (json \ "api").as(ApiIdFormat),
createdAt = (json \ "createdAt").as(DateTimeFormat),
validUntil = (json \ "validUntil").asOpt(DateTimeFormat),
by = (json \ "by").as(UserIdFormat),
customName = (json \ "customName").asOpt[String],
adminCustomName = (json \ "adminCustomName").asOpt[String],
Expand Down Expand Up @@ -2780,6 +2781,10 @@ object json {
"team" -> TeamIdFormat.writes(o.team),
"api" -> ApiIdFormat.writes(o.api),
"createdAt" -> DateTimeFormat.writes(o.createdAt),
"validUntil"-> o.validUntil
.map(DateTimeFormat.writes)
.getOrElse(JsNull)
.as[JsValue],
"by" -> UserIdFormat.writes(o.by),
"customName" -> o.customName
.map(id => JsString(id))
Expand Down Expand Up @@ -3126,7 +3131,9 @@ object json {
"rotation" -> apk.rotation
.map(ApiKeyRotationFormat.writes)
.getOrElse(JsNull)
.as[JsValue]
.as[JsValue],
"validUntil" -> apk.validUntil

)

override def reads(json: JsValue): JsResult[ActualOtoroshiApiKey] =
Expand Down Expand Up @@ -3161,7 +3168,8 @@ object json {
.asOpt[Set[String]]
.getOrElse(Set.empty[String]),
restrictions = (json \ "restrictions").as(ApiKeyRestrictionsFormat),
rotation = (json \ "rotation").asOpt(ApiKeyRotationFormat)
rotation = (json \ "rotation").asOpt(ApiKeyRotationFormat),
validUntil = (json \ "validUntil").asOpt[Long]
)
} map {
case sd => JsSuccess(sd)
Expand Down
2 changes: 2 additions & 0 deletions daikoku/app/jobs/OtoroshiVerifierJob.scala
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ class OtoroshiVerifierJob(
.map(_.apikeyCustomization.readOnly)
)
.getOrElse(infos.apk.readOnly),
validUntil = subscription.validUntil
.map(_.getMillis),
rotation = infos.apk.rotation
.map(r =>
r.copy(enabled =
Expand Down
9 changes: 6 additions & 3 deletions daikoku/app/utils/ApiService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class ApiService(
customMaxPerDay: Option[Long] = None,
customMaxPerMonth: Option[Long] = None,
customReadOnly: Option[Boolean] = None,
maybeOtoroshiApiKey: Option[OtoroshiApiKey] = None
maybeOtoroshiApiKey: Option[OtoroshiApiKey] = None,
) = {

val otoroshiApiKey = maybeOtoroshiApiKey.getOrElse(
Expand Down Expand Up @@ -162,7 +162,7 @@ class ApiService(
"daikoku__tags" -> processedTags.mkString(" | ")
) ++ processedMetadata,
rotation =
plan.autoRotation.map(enabled => ApiKeyRotation(enabled = enabled))
plan.autoRotation.map(enabled => ApiKeyRotation(enabled = enabled)),
)

plan match {
Expand Down Expand Up @@ -256,6 +256,7 @@ class ApiService(
apiKey = tunedApiKey.asOtoroshiApiKey,
plan = plan.id,
createdAt = DateTime.now(),
validUntil = None,
team = team.id,
api = api.id,
by = user.id,
Expand Down Expand Up @@ -359,6 +360,7 @@ class ApiService(
apiKey = OtoroshiApiKey(clientName, clientId, clientSecret),
plan = plan.id,
createdAt = DateTime.now(),
validUntil = None,
team = team.id,
api = api.id,
by = user.id,
Expand Down Expand Up @@ -759,7 +761,8 @@ class ApiService(
metadata = apiKey.metadata ++ subscription.customMetadata
.flatMap(_.asOpt[Map[String, String]])
.getOrElse(Map.empty[String, String]),
readOnly = subscription.customReadOnly.getOrElse(apiKey.readOnly)
readOnly = subscription.customReadOnly.getOrElse(apiKey.readOnly),
validUntil = subscription.validUntil.map(_.getMillis)
)
)(otoSettings)
)
Expand Down
Loading
Loading