Skip to content

Commit fe3ce2c

Browse files
author
Asaf Cohen
authored
Merge pull request #16 from permitio/asaf/per-7182-java-sdk-add-checkurl
Add support in check url and sharding key
2 parents 0b8b9b8 + f094ca5 commit fe3ce2c

4 files changed

Lines changed: 113 additions & 4 deletions

File tree

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,29 @@ This guide will walk you through the steps of installing the Permit.io Java SDK
99
## Installation
1010

1111
For [Maven](https://maven.apache.org/) projects, use:
12+
1213
```xml
1314
<dependency>
1415
<groupId>io.permit</groupId>
1516
<artifactId>permit-sdk-java</artifactId>
16-
<version>1.3.0</version>
17+
<version>1.4.0</version>
1718
</dependency>
1819
```
1920

2021
For [Gradle](https://gradle.org/) projects, configure `permit-sdk-java` as a dependency in your `build.gradle` file:
22+
2123
```groovy
2224
dependencies {
2325
// ...
2426
25-
implementation 'io.permit:permit-sdk-java:1.3.0'
27+
implementation 'io.permit:permit-sdk-java:1.4.0'
2628
}
2729
```
2830

2931
## Usage
3032

3133
### Initializing the SDK
34+
3235
To init the SDK, you need to create a new Permit client with the API key you got from the Permit.io dashboard.
3336

3437
First we will create a new `PermitConfig` object so we can pass it to the Permit client.
@@ -52,6 +55,7 @@ Permit permit = new Permit(
5255
```
5356

5457
### Checking permissions
58+
5559
To check permissions using our `permit.check()` method, you will have to create User and Resource models as input to the permission check.
5660
The models are located in ``
5761

@@ -80,6 +84,7 @@ if (permitted) {
8084
```
8185

8286
A more complicated example (passing attributes on the user object, using an explicit tenant in the resource):
87+
8388
```java
8489
import io.permit.sdk.enforcement.Resource;
8590
import io.permit.sdk.enforcement.User;
@@ -107,12 +112,14 @@ if (permitted) {
107112
```
108113

109114
### Syncing users
115+
110116
When the user first logins, and after you check if he authenticated successfully (i.e: **by checking the JWT access token**) -
111117
you need to declare the user in the permission system so you can run `permit.check()` on that user.
112118

113119
To declare (or "sync") a user in the Permit.io API, use the `permit.api.users.sync()` method.
114120

115121
Follow the example below:
122+
116123
```java
117124
import io.permit.sdk.api.models.CreateOrUpdateResult;
118125
import io.permit.sdk.enforcement.User;
@@ -140,6 +147,7 @@ CreateOrUpdateResult<UserRead> result = permit.api.users.sync(new UserCreate("[U
140147
```
141148

142149
## Javadoc reference
143-
To view the javadoc reference, [click here](https://javadoc.io/doc/io.permit/permit-sdk-java/1.3.0/index.html).
144150

145-
It's easiest to start with the root [Permit](https://javadoc.io/static/io.permit/permit-sdk-java/1.3.0/io/permit/sdk/Permit.html) class.
151+
To view the javadoc reference, [click here](https://javadoc.io/doc/io.permit/permit-sdk-java/1.4.0/index.html).
152+
153+
It's easiest to start with the root [Permit](https://javadoc.io/static/io.permit/permit-sdk-java/1.4.0/io/permit/sdk/Permit.html) class.

src/main/java/io/permit/sdk/Permit.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,14 @@ public boolean check(User user, String action, Resource resource, Context contex
127127
public boolean check(User user, String action, Resource resource) throws IOException {
128128
return this.enforcer.check(user, action, resource);
129129
}
130+
131+
@Override
132+
public boolean checkUrl(User user, String httpMethod, String url, String tenant, Context context) throws IOException {
133+
return this.enforcer.checkUrl(user, httpMethod, url, tenant, context);
134+
}
135+
136+
@Override
137+
public boolean checkUrl(User user, String httpMethod, String url, String tenant) throws IOException {
138+
return this.enforcer.checkUrl(user, httpMethod, url, tenant);
139+
}
130140
}

src/main/java/io/permit/sdk/enforcement/Enforcer.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,22 @@ class EnforcerInput {
4444
}
4545
}
4646

47+
class CheckUrlInput {
48+
public final User user;
49+
public final String http_method;
50+
public final String url;
51+
public final String tenant;
52+
public final HashMap<String, Object> context;
53+
54+
CheckUrlInput(User user, String http_method, String url, String tenant, HashMap<String, Object> context) {
55+
this.user = user;
56+
this.http_method = http_method;
57+
this.url = url;
58+
this.tenant = tenant;
59+
this.context = context;
60+
}
61+
}
62+
4763
/**
4864
* The {@code OpaResult} class represents the result of a Permit enforcement check returned by the policy agent.
4965
*/
@@ -118,6 +134,7 @@ public boolean check(User user, String action, Resource resource, Context contex
118134
.addHeader("Content-Type", "application/json")
119135
.addHeader("Authorization", String.format("Bearer %s", this.config.getToken()))
120136
.addHeader("X-Permit-SDK-Version", String.format("java:%s", this.config.version))
137+
.addHeader("X-Tenant-ID", normalizedResource.getTenant()) // sharding key
121138
.build();
122139

123140
try (Response response = client.newCall(request).execute()) {
@@ -172,4 +189,76 @@ public boolean check(User user, String action, Resource resource, Context contex
172189
public boolean check(User user, String action, Resource resource) throws IOException {
173190
return this.check(user, action, resource, new Context());
174191
}
192+
193+
@Override
194+
public boolean checkUrl(User user, String httpMethod, String url, String tenant, Context context) throws IOException {
195+
CheckUrlInput input = new CheckUrlInput(
196+
user,
197+
httpMethod,
198+
url,
199+
tenant,
200+
context
201+
);
202+
203+
// request body
204+
Gson gson = new Gson();
205+
String requestBody = gson.toJson(input);
206+
RequestBody body = RequestBody.create(requestBody, MediaType.parse("application/json"));
207+
208+
// create the request
209+
String apiUrl = String.format("%s/allowed_url", this.config.getPdpAddress());
210+
Request request = new Request.Builder()
211+
.url(apiUrl)
212+
.post(body)
213+
.addHeader("Content-Type", "application/json")
214+
.addHeader("Authorization", String.format("Bearer %s", this.config.getToken()))
215+
.addHeader("X-Permit-SDK-Version", String.format("java:%s", this.config.version))
216+
.addHeader("X-Tenant-ID", tenant) // sharding key
217+
.build();
218+
219+
try (Response response = client.newCall(request).execute()) {
220+
if (!response.isSuccessful()) {
221+
String errorMessage = String.format(
222+
"Error in permit.checkUrl(%s, %s, %s, %s): got unexpected status code %d",
223+
user.toString(),
224+
httpMethod,
225+
url,
226+
tenant,
227+
response.code()
228+
);
229+
logger.error(errorMessage);
230+
throw new IOException(errorMessage);
231+
}
232+
ResponseBody responseBody = response.body();
233+
if (responseBody == null) {
234+
String errorMessage = String.format(
235+
"Error in permit.check(%s, %s, %s, %s): got empty response",
236+
user,
237+
httpMethod,
238+
url,
239+
tenant
240+
);
241+
logger.error(errorMessage);
242+
throw new IOException(errorMessage);
243+
}
244+
String responseString = responseBody.string();
245+
OpaResult result = gson.fromJson(responseString, OpaResult.class);
246+
if (this.config.isDebugMode()) {
247+
logger.info(String.format(
248+
"permit.check(%s, %s, %s, %s) = %s",
249+
user,
250+
httpMethod,
251+
url,
252+
tenant,
253+
result.allow.toString()
254+
));
255+
}
256+
return result.allow;
257+
}
258+
}
259+
260+
@Override
261+
public boolean checkUrl(User user, String httpMethod, String url, String tenant) throws IOException {
262+
return this.checkUrl(user, httpMethod, url, tenant, new Context());
263+
}
175264
}

src/main/java/io/permit/sdk/enforcement/IEnforcerApi.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@
77
public interface IEnforcerApi {
88
boolean check(User user, String action, Resource resource, Context context) throws IOException;
99
boolean check(User user, String action, Resource resource) throws IOException;
10+
boolean checkUrl(User user, String httpMethod, String url, String tenant) throws IOException;
11+
boolean checkUrl(User user, String httpMethod, String url, String tenant, Context context) throws IOException;
1012
}

0 commit comments

Comments
 (0)