All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.baulsupp.oksocial.services.microsoft.MicrosoftAuthInterceptor.kt Maven / Gradle / Ivy

The newest version!
package com.baulsupp.oksocial.services.microsoft

import com.baulsupp.oksocial.authenticator.AuthInterceptor
import com.baulsupp.oksocial.authenticator.ValidatedCredentials
import com.baulsupp.oksocial.authenticator.oauth2.Oauth2ServiceDefinition
import com.baulsupp.oksocial.authenticator.oauth2.Oauth2Token
import com.baulsupp.oksocial.completion.ApiCompleter
import com.baulsupp.oksocial.completion.BaseUrlCompleter
import com.baulsupp.oksocial.completion.CompletionVariableCache
import com.baulsupp.oksocial.completion.UrlList
import com.baulsupp.oksocial.credentials.CredentialsStore
import com.baulsupp.oksocial.credentials.TokenValue
import com.baulsupp.oksocial.kotlin.query
import com.baulsupp.oksocial.output.OutputHandler
import com.baulsupp.oksocial.secrets.Secrets
import com.baulsupp.oksocial.services.microsoft.model.DriveRootList
import com.baulsupp.oksocial.services.microsoft.model.Token
import com.baulsupp.oksocial.services.microsoft.model.User
import okhttp3.FormBody
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response

/**
 * https://graph.microsoft.io/en-us/docs/authorization/app_authorization
 * http://graph.microsoft.io/en-us/docs/authorization/permission_scopes
 */
class MicrosoftAuthInterceptor : AuthInterceptor() {
  override val serviceDefinition = Oauth2ServiceDefinition("graph.microsoft.com", "Microsoft API", "microsoft",
    "https://graph.microsoft.io/en-us/docs/get-started/rest",
    "https://apps.dev.microsoft.com/#/appList")

  override fun intercept(chain: Interceptor.Chain, credentials: Oauth2Token): Response {
    var request = chain.request()

    val token = credentials.accessToken

    request = request.newBuilder().addHeader("Authorization", "Bearer $token").build()

    return chain.proceed(request)
  }

  override suspend fun authorize(
    client: OkHttpClient,
    outputHandler: OutputHandler,
    authArguments: List
  ): Oauth2Token {

    val clientId = Secrets.prompt("Microsoft Client Id", "microsoft.clientId", "", false)
    val clientSecret = Secrets.prompt("Microsoft Client Secret", "microsoft.clientSecret", "", true)

    val scopes = Secrets.promptArray("Scopes", "microsoft.scopes", listOf(
      "User.Read", "Contacts.Read", "Calendars.Read", "Mail.Read", "email", "offline_access", "openid", "profile", "Files.ReadWrite"
    ))

    return MicrosoftAuthFlow.login(client, outputHandler, clientId, clientSecret, scopes)
  }

  override fun canRenew(credentials: Oauth2Token): Boolean {
    return credentials.isRenewable()
  }

  override suspend fun renew(client: OkHttpClient, credentials: Oauth2Token): Oauth2Token? {

    val body = FormBody.Builder().add("grant_type", "refresh_token")
      .add("redirect_uri", "http://localhost:3000/callback")
      .add("client_id", credentials.clientId!!)
      .add("client_secret", credentials.clientSecret!!)
      .add("refresh_token", credentials.refreshToken!!)
      .build()

    val request = Request.Builder().url("https://login.microsoftonline.com/common/oauth2/v2.0/token")
      .post(body)
      .build()

    val responseMap = client.query(request)

    return Oauth2Token(responseMap.access_token, responseMap.refresh_token, credentials.clientId, credentials.clientSecret)
  }

  override fun apiCompleter(
    prefix: String,
    client: OkHttpClient,
    credentialsStore: CredentialsStore,
    completionVariableCache: CompletionVariableCache,
    tokenSet: com.baulsupp.oksocial.credentials.Token
  ): ApiCompleter {
    val urlList = UrlList.fromResource(name())

    val completer = BaseUrlCompleter(urlList!!, hosts(), completionVariableCache)

    completer.withCachedVariable(name(), "itemId", {
      credentialsStore.get(serviceDefinition, tokenSet)?.let {
        client.query("https://graph.microsoft.com/v1.0/me/drive/root/children", tokenSet).value.map { it.id }
      }
    })

    return completer
  }

  override suspend fun validate(client: OkHttpClient, credentials: Oauth2Token): ValidatedCredentials =
    ValidatedCredentials(client.query("https://graph.microsoft.com/v1.0/me", TokenValue(credentials)).displayName)

  override fun hosts(): Set = setOf("graph.microsoft.com")
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy