Skip to content

Commit

Permalink
Implement new GoogleCalendarApiWrapper component
Browse files Browse the repository at this point in the history
Now to build up the main abstraction layer for calendars. Maybe PartialCalendar/FullCalendar? TBD
  • Loading branch information
NovaFox161 committed Oct 27, 2024
1 parent b40ed04 commit 1166303
Show file tree
Hide file tree
Showing 11 changed files with 424 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.dreamexposure.discal.cam.business.google

import org.dreamexposure.discal.core.business.CalendarService
import org.dreamexposure.discal.core.business.CredentialService
import org.dreamexposure.discal.core.business.api.GoogleCalendarApiWrapper
import org.dreamexposure.discal.core.business.api.GoogleAuthApiWrapper
import org.dreamexposure.discal.core.exceptions.EmptyNotAllowedException
import org.dreamexposure.discal.core.exceptions.NotFoundException
import org.dreamexposure.discal.core.extensions.isExpiredTtl
Expand All @@ -17,14 +17,14 @@ import java.time.Instant
class GoogleAuthService(
private val credentialService: CredentialService,
private val calendarService: CalendarService,
private val googleCalendarApiWrapper: GoogleCalendarApiWrapper,
private val googleAuthApiWrapper: GoogleAuthApiWrapper,
) {
suspend fun requestNewAccessToken(calendar: CalendarMetadata): TokenV1Model? {
if (!calendar.secrets.expiresAt.isExpiredTtl()) return TokenV1Model(calendar.secrets.accessToken, calendar.secrets.expiresAt)

LOGGER.debug("Refreshing access token | guildId:{} | calendar:{}", calendar.guildId, calendar.number)

val refreshed = googleCalendarApiWrapper.refreshAccessToken(calendar.secrets.refreshToken).entity ?: return null
val refreshed = googleAuthApiWrapper.refreshAccessToken(calendar.secrets.refreshToken).entity ?: return null
calendar.secrets.accessToken = refreshed.accessToken
calendar.secrets.expiresAt = Instant.now().plusSeconds(refreshed.expiresIn.toLong()).minus(Duration.ofMinutes(5)) // Add some wiggle room
calendarService.updateCalendarMetadata(calendar)
Expand All @@ -40,7 +40,7 @@ class GoogleAuthService(

LOGGER.debug("Refreshing access token | credentialId:$credentialId")

val refreshed = googleCalendarApiWrapper.refreshAccessToken(credential.refreshToken).entity ?: throw EmptyNotAllowedException()
val refreshed = googleAuthApiWrapper.refreshAccessToken(credential.refreshToken).entity ?: throw EmptyNotAllowedException()
credential.accessToken = refreshed.accessToken
credential.expiresAt = Instant.now().plusSeconds(refreshed.expiresIn.toLong()).minus(Duration.ofMinutes(5)) // Add some wiggle room
credentialService.updateCredential(credential)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.dreamexposure.discal.core.business.api

import okhttp3.FormBody
import okhttp3.Request
import org.dreamexposure.discal.core.config.Config
import org.dreamexposure.discal.core.exceptions.AccessRevokedException
import org.dreamexposure.discal.core.logger.LOGGER
import org.dreamexposure.discal.core.`object`.new.model.ResponseModel
import org.dreamexposure.discal.core.`object`.new.model.google.OauthV4RefreshTokenResponse
import org.dreamexposure.discal.core.utils.GlobalVal.DEFAULT
import org.springframework.stereotype.Component

@Component
class GoogleAuthApiWrapper(
private val apiWrapperClient: ApiWrapperClient,
) {
suspend fun refreshAccessToken(refreshToken: String): ResponseModel<OauthV4RefreshTokenResponse> {
val requestFormBody = FormBody.Builder()
.addEncoded("client_id", Config.SECRET_GOOGLE_CLIENT_ID.getString())
.addEncoded("client_secret", Config.SECRET_GOOGLE_CLIENT_SECRET.getString())
.addEncoded("refresh_token", refreshToken)
.addEncoded("grant_type", "refresh_token")
.build()
val request = Request.Builder()
.url("https://www.googleapis.com/oauth2/v4/token")
.post(requestFormBody)
.header("Content-Type", "application/x-www-form-urlencoded")
.build()

val response = apiWrapperClient.makeRequest(request, OauthV4RefreshTokenResponse::class.java)


// TODO: Handling of this should be moved up higher in the impl?
if (response.error?.error == "invalid_grant") {
LOGGER.debug(DEFAULT, "Google Oauth invalid_grant for access token refresh")
throw AccessRevokedException() // TODO: How should I handle this for external calendars? Right now we just delete everything
} else if (response.error != null) {
LOGGER.error(DEFAULT, "[Google] Error requesting new access token | ${response.code} | ${response.error.error}")
}

return response
}
}
Loading

0 comments on commit 1166303

Please sign in to comment.