Skip to content

Commit

Permalink
java integration test working, add cron trigger (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesdaniels committed May 17, 2024
1 parent 817855d commit 9ebaaee
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 13 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: CI
on:
workflow_dispatch: {}
pull_request: {}
push:
schedule:
- cron: 0 0 * * *

# When a new revision is pushed to a PR, cancel all in-progress CI runs for that
# PR. See https://docs.github.com/en/actions/using-jobs/using-concurrency
Expand All @@ -17,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
server: [node, csharp] #TODO: java
server: [node, csharp, java]
steps:
- name: Check out code
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion server/java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dependencies {
implementation 'com.jayway.jsonpath:json-path:2.9.0'
implementation 'commons-io:commons-io:2.15.1'

implementation group: 'com.styra', name: 'opa', version: '0.6.18'
implementation group: 'com.styra', name: 'opa', version: '+'

}

Expand Down
2 changes: 1 addition & 1 deletion server/java/src/main/java/com/styra/tickethub/Storage.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public List<Ticket> getTickets(String tenant) {

public synchronized Ticket addTicket(String tenant, Ticket ticket) {
var tickets = this.tenants.computeIfAbsent(tenant, (ignored) -> new Vector<>());
var newTicket = ticket.withId(tickets.size());
var newTicket = ticket.withId(tickets.size()+1);
tickets.add(newTicket);
return newTicket;
}
Expand Down
60 changes: 50 additions & 10 deletions server/java/src/main/java/com/styra/tickethub/TicketHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.ForbiddenException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
Expand All @@ -27,13 +28,15 @@
import java.util.Optional;
import java.util.Map;
import static java.util.Map.entry;
import jakarta.ws.rs.NotAllowedException;
import jakarta.ws.rs.ForbiddenException;


import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Path("/")
public class TicketHub {
Expand All @@ -60,7 +63,7 @@ public TicketHub() {
@Produces({MediaType.APPLICATION_JSON})
public Tickets getTickets() {
if (!authz()) {
throw new NotAllowedException("Not authorized");
throw new ForbiddenException("Not authorized");
}
return new Tickets(storage.getTickets(getTenant()));
}
Expand All @@ -70,13 +73,23 @@ public Tickets getTickets() {
@Produces(MediaType.APPLICATION_JSON)
public Ticket getTicket(@PathParam("id") int id) {
if (!authz()) {
throw new NotAllowedException("Not authorized");
throw new ForbiddenException("Not authorized");
}

// This will perform poorly with a large number of tickets, but since
// this is just a demo it should never have more than a few dozen.
var tickets = storage.getTickets(getTenant());
var ticket = tickets.get(id);
Ticket ticket = null;
for (Ticket t : tickets) {
if (t.getId() == id) {
ticket = t;
break;
}
}
if (ticket == null) {
throw new NotFoundException();
}

return ticket;
}

Expand All @@ -86,7 +99,7 @@ public Ticket getTicket(@PathParam("id") int id) {
@Produces(MediaType.APPLICATION_JSON)
public Ticket addTicket(Ticket ticket) {
if (!authz()) {
throw new NotAllowedException("Not authorized");
throw new ForbiddenException("Not authorized");
}
return storage.addTicket(getTenant(), ticket);
}
Expand All @@ -96,10 +109,16 @@ public Ticket addTicket(Ticket ticket) {
@Produces(MediaType.APPLICATION_JSON)
public Ticket resolveTicket(@PathParam("id") int id, TicketStatus status) {
if (!authz()) {
throw new NotAllowedException("Not authorized");
throw new ForbiddenException("Not authorized");
}
var tickets = storage.getTickets(getTenant());
var ticket = tickets.get(id);
Ticket ticket = null;
for (Ticket t : tickets) {
if (t.getId() == id) {
ticket = t;
break;
}
}
if (ticket == null) {
throw new NotFoundException();
}
Expand Down Expand Up @@ -154,17 +173,36 @@ static String getSessionMethod(HttpServletRequest request) {
}

private boolean authz() {
System.out.printf("DEBUG: %s %s %s\n", getSessionPath(), getSessionMethod(), getSessionAttributes());
String path = getSessionPath();
String action = getSessionMethod().toLowerCase();

// An ugly kludge to decide what the action should be for the policy.
// At a minimum, we probably don't need to recompile the regexes for
// every single request. [0-9]+ also matches some invalid (non-int)
// IDs.
if (path == "/tickets") {
action = "list";
}

if (Pattern.compile("^/tickets/[0-9]+$").matcher(path).find()) {
action = "get";
}

if (Pattern.compile("^/tickets/[0-9]+/resolve$").matcher(path).find()) {
action = "resolve";
}

java.util.Map<String, Object> iMap = java.util.Map.ofEntries(
entry("path", getSessionPath()),
entry("path", path),
entry("method", getSessionMethod()),
entry("cookie", getSessionAttributes()),
entry("user", getSessionAttributes().get("subject")),
entry("tenant", getSessionAttributes().get("tenant")),
entry("action", getSessionMethod().toLowerCase())
entry("action", action)
);

System.out.printf("DEBUG: OPA input is: %s\n", iMap);

boolean allow;

try {
Expand All @@ -174,6 +212,8 @@ private boolean authz() {
return false;
}

System.out.printf("DEBUG: %s %s %s %b\n", getSessionPath(), getSessionMethod(), getSessionAttributes(), allow);

return allow;
}

Expand Down

0 comments on commit 9ebaaee

Please sign in to comment.