-
Notifications
You must be signed in to change notification settings - Fork 653
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ./gradlew push${MainService}ApolloOperations (#3403)
* add RegisterOperations * add ApolloRegisterOperationsTask * add a test case * fix bad copy/paste * update metalava signatures * add some doc * Update docs/source/advanced/operation-safelisting.mdx Co-authored-by: Benoit Lubek <BoD@JRAF.org> * Update docs/source/advanced/operation-safelisting.mdx Co-authored-by: Benoit Lubek <BoD@JRAF.org> * add the link to the operation registry server documentation Co-authored-by: Benoit Lubek <BoD@JRAF.org>
- Loading branch information
1 parent
e48d5f8
commit 696c1af
Showing
15 changed files
with
288 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
...le-plugin/src/main/kotlin/com/apollographql/apollo/gradle/api/RegisterOperationsConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.apollographql.apollo.gradle.api | ||
|
||
import org.gradle.api.provider.Property | ||
|
||
interface RegisterOperationsConfig { | ||
val key: Property<String> | ||
|
||
val graph: Property<String> | ||
|
||
val graphVariant: Property<String> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
.../src/main/kotlin/com/apollographql/apollo/gradle/internal/ApolloRegisterOperationsTask.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.apollographql.apollo.gradle.internal | ||
|
||
import com.apollographql.apollo.compiler.operationoutput.OperationOutput | ||
import org.gradle.api.DefaultTask | ||
import org.gradle.api.file.RegularFileProperty | ||
import org.gradle.api.provider.Property | ||
import org.gradle.api.tasks.Input | ||
import org.gradle.api.tasks.InputFile | ||
import org.gradle.api.tasks.TaskAction | ||
|
||
abstract class ApolloRegisterOperationsTask: DefaultTask() { | ||
@get:InputFile | ||
abstract val operationOutput: RegularFileProperty | ||
|
||
@get:Input | ||
abstract val key: Property<String> | ||
|
||
@get:Input | ||
abstract val graph: Property<String> | ||
|
||
@get:Input | ||
abstract val graphVariant: Property<String> | ||
|
||
@TaskAction | ||
fun taskAction() { | ||
RegisterOperations.registerOperations( | ||
key = key.get() ?: error("key is required to register operations"), | ||
graphID = graph.get() ?: error("graphID is required to register operations"), | ||
graphVariant = graphVariant.get() ?: error("graphVariant is required to register operations"), | ||
operationOutput = OperationOutput(operationOutput.get().asFile) | ||
) | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...c/main/kotlin/com/apollographql/apollo/gradle/internal/DefaultRegisterOperationsConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.apollographql.apollo.gradle.internal | ||
|
||
import com.apollographql.apollo.gradle.api.RegisterOperationsConfig | ||
import org.gradle.api.provider.Property | ||
|
||
abstract class DefaultRegisterOperationsConfig: RegisterOperationsConfig { | ||
abstract override val key: Property<String> | ||
abstract override val graph: Property<String> | ||
abstract override val graphVariant: Property<String> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
...dle-plugin/src/main/kotlin/com/apollographql/apollo/gradle/internal/RegisterOperations.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package com.apollographql.apollo.gradle.internal | ||
|
||
import com.apollographql.apollo.compiler.fromJson | ||
import com.apollographql.apollo.compiler.operationoutput.OperationOutput | ||
import com.apollographql.apollo.gradle.internal.SchemaDownloader.cast | ||
import org.jetbrains.kotlin.gradle.utils.`is` | ||
|
||
object RegisterOperations { | ||
private val mutation = """ | ||
mutation RegisterOperations( | ||
${'$'}id : ID! | ||
${'$'}clientIdentity : RegisteredClientIdentityInput! | ||
${'$'}operations : [RegisteredOperationInput!]! | ||
${'$'}manifestVersion : Int! | ||
${'$'}graphVariant : String | ||
) { | ||
service(id: ${'$'}id ) { | ||
registerOperationsWithResponse( | ||
clientIdentity: ${'$'}clientIdentity | ||
operations: ${'$'}operations | ||
manifestVersion: ${'$'}manifestVersion | ||
graphVariant: ${'$'}graphVariant | ||
) { | ||
invalidOperations { | ||
errors { | ||
message | ||
} | ||
signature | ||
} | ||
newOperations { | ||
signature | ||
} | ||
registrationSuccess | ||
} | ||
} | ||
} | ||
""".trimIndent() | ||
|
||
fun registerOperations( | ||
key: String, | ||
graphID: String, | ||
graphVariant: String, | ||
operationOutput: OperationOutput | ||
) { | ||
val variables = mapOf( | ||
"id" to graphID, | ||
"clientIdentity" to mapOf( | ||
"name" to "apollo-android", | ||
"identifier" to "apollo-android", | ||
"version" to com.apollographql.apollo.compiler.VERSION, | ||
), | ||
"operations" to operationOutput.entries.map { | ||
mapOf( | ||
"signature" to it.key, | ||
"document" to it.value.source | ||
) | ||
}, | ||
"manifestVersion" to 2, | ||
"graphVariant" to graphVariant | ||
) | ||
|
||
val response = SchemaHelper.executeQuery(mutation, variables, "https://graphql.api.apollographql.com/api/graphql", mapOf("x-api-key" to key)) | ||
|
||
check(response.isSuccessful) | ||
|
||
val responseString = response.body.use { it?.string() } | ||
|
||
val errors = responseString | ||
?.fromJson<Map<String, *>>() | ||
?.get("data").cast<Map<String, *>>() | ||
?.get("service").cast<Map<String, *>>() | ||
?.get("registerOperationsWithResponse").cast<Map<String, *>>() | ||
?.get("invalidOperations").cast<List<Map<String, *>>>() | ||
?.flatMap { | ||
it.get("errors").cast<List<String>>() ?: emptyList() | ||
} ?: emptyList() | ||
|
||
check(errors.isEmpty()) { | ||
"Cannot push operations: ${errors.joinToString("\n")}" | ||
} | ||
|
||
val success = responseString | ||
?.fromJson<Map<String, *>>() | ||
?.get("data").cast<Map<String, *>>() | ||
?.get("service").cast<Map<String, *>>() | ||
?.get("registerOperationsWithResponse").cast<Map<String, *>>() | ||
?.get("registrationSuccess").cast<Boolean>() | ||
?: false | ||
|
||
check(success) { | ||
"Cannot push operations: $responseString" | ||
} | ||
|
||
println("Operations pushed successfully") | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
apollo-gradle-plugin/testProjects/register-operations/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import com.apollographql.apollo.gradle.api.ApolloExtension | ||
import com.apollographql.apollo.compiler.operationoutput.OperationOutput | ||
import com.apollographql.apollo.compiler.operationoutput.OperationDescriptor | ||
import com.apollographql.apollo.compiler.OperationOutputGenerator | ||
|
||
buildscript { | ||
apply(from = "../../../gradle/dependencies.gradle") | ||
|
||
repositories { | ||
maven { | ||
url = uri("../../../build/localMaven") | ||
} | ||
mavenCentral() | ||
} | ||
dependencies { | ||
classpath(groovy.util.Eval.x(project, "x.dep.kotlin.plugin")) | ||
classpath(groovy.util.Eval.x(project, "x.dep.apollo.plugin")) | ||
} | ||
} | ||
|
||
apply(plugin = "org.jetbrains.kotlin.jvm") | ||
apply(plugin = "com.apollographql.apollo") | ||
|
||
repositories { | ||
maven { | ||
url = uri("../../../build/localMaven") | ||
} | ||
mavenCentral() | ||
} | ||
|
||
configure<ApolloExtension> { | ||
service("service") { | ||
registerOperations { | ||
key.set(System.getenv("APOLLO_KEY")) | ||
graph.set(System.getenv("APOLLO_GRAPH")) | ||
graphVariant.set("current") | ||
} | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
apollo-gradle-plugin/testProjects/register-operations/settings.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
rootProject.name="registerOperations" | ||
|
3 changes: 3 additions & 0 deletions
3
...le-plugin/testProjects/register-operations/src/main/graphql/com/example/TestQuery.graphql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
query Greeting { | ||
greeting | ||
} |
4 changes: 4 additions & 0 deletions
4
...lo-gradle-plugin/testProjects/register-operations/src/main/graphql/com/example/schema.sdl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
type Query { | ||
greeting: String | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
title: Operation safelisting | ||
sidebar_title: Operation safelisting (enterprise only) | ||
description: Secure your graph by enforcing a safelist of registered operations | ||
--- | ||
|
||
import { ExpansionPanel } from 'gatsby-theme-apollo-docs'; | ||
|
||
## Overview | ||
|
||
> **Operation safelisting requires an Apollo Studio [Enterprise plan](https://www.apollographql.com/plans/).** To enable this feature, please contact Apollo. | ||
If you enabled operation safelisting on your backend (see [here](https://www.apollographql.com/docs/studio/operation-registry/) for more information about how to do this), you can use Apollo Android Gradle plugin to register your operations automatically. Apollo Android might transform the GraphQL files you write to include `__typename` (for polymorphic types) or trim whitespaces (to save some space). Registering your operations through the Gradle plugin ensures the transformed versions are registered so that there is an exact match between what is registered and what is sent by your app. | ||
|
||
Add this to your Gradle configuration: | ||
|
||
```kotlin | ||
apollo { | ||
service("$serviceName") { | ||
|
||
// Configure operation safelisting | ||
registerOperations { | ||
// You can get a key at https://studio.apollographql.com/graph/$graphId/settings | ||
key.set(System.getenv("APOLLO_KEY")) | ||
// Configure your graph. | ||
graph.set(System.getenv("APOLLO_GRAPH")) | ||
// Configure your variant. | ||
graphVariant.set("current") | ||
} | ||
} | ||
} | ||
``` | ||
|
||
When your operations are stable and you want to safelist them, execute the `registerMain${serviceName}ApolloOperations` task to push all your operation to the registry. | ||
|
||
```kotlin | ||
./gradlew registerMainServiceApolloOperations | ||
``` | ||
|
||
If everything goes well, your queries are now safelisted and safe to use in your mobile app. |