-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from authzed/client-token
Add ClientToken util class Add example apps
- Loading branch information
Showing
4 changed files
with
255 additions
and
0 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
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,121 @@ | ||
/* | ||
* Authzed API examples | ||
*/ | ||
package v0; | ||
|
||
import com.authzed.grpcutil.BearerToken; | ||
import com.authzed.api.v0.ACLServiceGrpc; | ||
import com.authzed.api.v0.AclService; | ||
import com.authzed.api.v0.Core; | ||
import io.grpc.*; | ||
|
||
import java.util.concurrent.Executor; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
public class App { | ||
private static final Logger logger = Logger.getLogger(App.class.getName()); | ||
private static final String target = "grpc.authzed.com:443"; | ||
private static final String token = "tc_test_def_token"; | ||
|
||
private final ACLServiceGrpc.ACLServiceBlockingStub v0blockingStub; | ||
|
||
public App(Channel channel) { | ||
blockingStub = SchemaServiceGrpc.newBlockingStub(channel); | ||
v0blockingStub = ACLServiceGrpc.newBlockingStub(channel); | ||
} | ||
|
||
public static void main(String[] args) { | ||
ManagedChannel channel = ManagedChannelBuilder | ||
.forTarget(target) | ||
.useTransportSecurity() | ||
.build(); | ||
try { | ||
App client = new App(channel); | ||
client.relationship(); | ||
client.check(); | ||
} finally { | ||
try { | ||
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); | ||
} catch (InterruptedException e) { | ||
// Uh oh! | ||
} | ||
} | ||
} | ||
|
||
public String relationship() { | ||
logger.info("Write relationship..."); | ||
AclService.WriteRequest request = AclService.WriteRequest | ||
.newBuilder() | ||
.addUpdates( | ||
Core.RelationTupleUpdate | ||
.newBuilder() | ||
.setOperationValue(Core.RelationTupleUpdate.Operation.CREATE_VALUE) | ||
.setTuple( | ||
Core.RelationTuple | ||
.newBuilder() | ||
.setUser(createUser("thelargeapp/user", "emilia", "...")) | ||
.setObjectAndRelation(createONR("thelargeapp/article", "java_test", "author")) | ||
) | ||
.build()) | ||
.build(); | ||
|
||
AclService.WriteResponse response; | ||
try { | ||
response = v0blockingStub | ||
.withCallCredentials(new BearerToken(token)) | ||
.write(request); | ||
} catch (Exception e) { | ||
logger.log(Level.WARNING, "RPC failed: {0}", e.getMessage()); | ||
return ""; | ||
} | ||
logger.info("Response: " + response.toString()); | ||
return response.toString(); | ||
} | ||
|
||
public String check() { | ||
logger.info("Checking..."); | ||
Core.User emilia = createUser("thelargeapp/user", "emilia", "..."); | ||
Core.ObjectAndRelation reader = createONR("thelargeapp/article", "java_test", "can_comment"); | ||
AclService.CheckRequest request = AclService.CheckRequest | ||
.newBuilder() | ||
.setUser(emilia) | ||
.setTestUserset(reader) | ||
.build(); | ||
AclService.CheckResponse response; | ||
try { | ||
response = v0blockingStub | ||
.withCallCredentials(new BearerToken(token)) | ||
.check(request); | ||
} catch (Exception e) { | ||
logger.log(Level.WARNING, "RPC failed: {0}", e.getMessage()); | ||
return ""; | ||
} | ||
logger.info("Response: " + response.toString()); | ||
return response.toString(); | ||
} | ||
|
||
private Core.ObjectAndRelation createONR(String namespace, String objId, String relation) { | ||
return Core.ObjectAndRelation | ||
.newBuilder() | ||
.setNamespace(namespace) | ||
.setObjectId(objId) | ||
.setRelation(relation) | ||
.build(); | ||
} | ||
|
||
private Core.User createUser(String namespace, String objId, String relation) { | ||
return Core.User | ||
.newBuilder() | ||
.setUserset( | ||
Core.ObjectAndRelation | ||
.newBuilder() | ||
.setNamespace(namespace) | ||
.setObjectId(objId) | ||
.setRelation(relation) | ||
.build() | ||
) | ||
.build(); | ||
} | ||
} |
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,93 @@ | ||
/* | ||
* Authzed API examples | ||
*/ | ||
package v1alpha1; | ||
|
||
import com.authzed.grpcutil.BearerToken; | ||
import com.authzed.api.v1alpha1.Schema; | ||
import com.authzed.api.v1alpha1.SchemaServiceGrpc; | ||
import io.grpc.*; | ||
|
||
import java.util.concurrent.Executor; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
public class App { | ||
private static final Logger logger = Logger.getLogger(App.class.getName()); | ||
private static final String target = "grpc.authzed.com:443"; | ||
private static final String token = "tc_test_def_token"; | ||
|
||
private final SchemaServiceGrpc.SchemaServiceBlockingStub blockingStub; | ||
|
||
public App(Channel channel) { | ||
blockingStub = SchemaServiceGrpc.newBlockingStub(channel); | ||
v0blockingStub = ACLServiceGrpc.newBlockingStub(channel); | ||
} | ||
|
||
public static void main(String[] args) { | ||
ManagedChannel channel = ManagedChannelBuilder | ||
.forTarget(target) | ||
.useTransportSecurity() | ||
.build(); | ||
try { | ||
App client = new App(channel); | ||
client.writeSchema(); | ||
client.readSchema(); | ||
} finally { | ||
try { | ||
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); | ||
} catch (InterruptedException e) { | ||
// Uh oh! | ||
} | ||
} | ||
} | ||
|
||
public String readSchema() { | ||
logger.info("Reading schema..."); | ||
Schema.ReadSchemaRequest request = Schema.ReadSchemaRequest | ||
.newBuilder() | ||
.addObjectDefinitionsNames("thelargeapp/article") | ||
.build(); | ||
Schema.ReadSchemaResponse response; | ||
try { | ||
response = blockingStub | ||
.withCallCredentials(new BearerToken(token)) | ||
.readSchema(request); | ||
} catch (Exception e) { | ||
logger.log(Level.WARNING, "RPC failed: {0}", e.getMessage()); | ||
return ""; | ||
} | ||
logger.info("Greeting: " + response.toString()); | ||
return response.toString(); | ||
} | ||
|
||
public String writeSchema() { | ||
logger.info("Writing schema..."); | ||
String schema = """ | ||
definition thelargeapp/article { | ||
relation author: thelargeapp/user | ||
relation commenter: thelargeapp/user | ||
permission can_comment = commenter + author | ||
} | ||
definition thelargeapp/user {} | ||
"""; | ||
Schema.WriteSchemaRequest request = Schema.WriteSchemaRequest | ||
.newBuilder() | ||
.setSchema(schema) | ||
.build(); | ||
Schema.WriteSchemaResponse response; | ||
try { | ||
response = blockingStub | ||
.withCallCredentials(new BearerToken(token)) | ||
.writeSchema(request); | ||
} catch (Exception e) { | ||
logger.log(Level.WARNING, "RPC failed: {0}", e.getMessage()); | ||
return ""; | ||
} | ||
logger.info("Response: " + response.toString()); | ||
return response.toString(); | ||
} | ||
} |
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 @@ | ||
package com.authzed.grpcutil; | ||
|
||
import io.grpc.*; | ||
|
||
import java.util.concurrent.Executor; | ||
|
||
/** | ||
* Bearer token implementation that can be used with GRPC stubs. | ||
*/ | ||
public class BearerToken extends CallCredentials { | ||
public static final String AUTHORIZATION = "authorization"; | ||
private static final Metadata.Key<String> META_DATA_KEY = | ||
Metadata.Key.of(AUTHORIZATION, Metadata.ASCII_STRING_MARSHALLER); | ||
|
||
private final String token; | ||
private final String header; | ||
|
||
public BearerToken(String value) { | ||
this.token = value; | ||
this.header = "Bearer " + token; | ||
} | ||
|
||
@Override | ||
public void applyRequestMetadata(RequestInfo requestInfo, Executor executor, MetadataApplier applier) { | ||
executor.execute(() -> { | ||
try { | ||
Metadata headers = new Metadata(); | ||
headers.put(META_DATA_KEY, header); | ||
applier.apply(headers); | ||
} catch (Throwable e) { | ||
applier.fail(Status.UNAUTHENTICATED.withCause(e)); | ||
} | ||
}); | ||
} | ||
|
||
@Override | ||
public void thisUsesUnstableApi() { | ||
// Intentionally empty | ||
} | ||
} |