diff --git a/docs/content/dev/authorization.md b/docs/content/dev/authorization.md index 61a680e5c..59d5a81fa 100644 --- a/docs/content/dev/authorization.md +++ b/docs/content/dev/authorization.md @@ -13,17 +13,34 @@ layout: page Implement `TaskAuthorizationProvider` to control per-user access: ```java +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import jakarta.enterprise.context.ApplicationScoped; + +import org.a2aproject.sdk.server.ServerCallContext; +import org.a2aproject.sdk.server.auth.TaskAuthorizationProvider; +import org.a2aproject.sdk.server.auth.TaskOperation; + @ApplicationScoped public class MyTaskAuthorizationProvider implements TaskAuthorizationProvider { + private final ConcurrentMap ownershipStore = new ConcurrentHashMap<>(); @Override public boolean checkRead(ServerCallContext context, String taskId, TaskOperation op) { - return isOwner(context.getUser(), taskId); + return isOwner(context, taskId); + } + + private boolean isOwner(ServerCallContext context, String taskId) { + String owner = ownershipStore.get(taskId); + return owner != null + && context.getUser() != null + && owner.equals(context.getUser().getUsername()); } @Override public boolean checkWrite(ServerCallContext context, String taskId, TaskOperation op) { - return isOwner(context.getUser(), taskId); + return isOwner(context, taskId); } @Override @@ -39,7 +56,7 @@ public class MyTaskAuthorizationProvider implements TaskAuthorizationProvider { @Override public void recordOwnership(ServerCallContext context, String taskId, TaskOperation op) { if (context.getUser() != null) { - ownershipStore.put(taskId, context.getUser().getUsername()); + ownershipStore.putIfAbsent(taskId, context.getUser().getUsername()); } } } diff --git a/server-common/src/main/java/org/a2aproject/sdk/server/auth/TaskAuthorizationProvider.java b/server-common/src/main/java/org/a2aproject/sdk/server/auth/TaskAuthorizationProvider.java index b093db5d8..3bebd8771 100644 --- a/server-common/src/main/java/org/a2aproject/sdk/server/auth/TaskAuthorizationProvider.java +++ b/server-common/src/main/java/org/a2aproject/sdk/server/auth/TaskAuthorizationProvider.java @@ -21,34 +21,51 @@ * configuration is required. * *
{@code
+ * import java.util.concurrent.ConcurrentHashMap;
+ * import java.util.concurrent.ConcurrentMap;
+ *
+ * import jakarta.enterprise.context.ApplicationScoped;
+ *
+ * import org.a2aproject.sdk.server.ServerCallContext;
+ * import org.a2aproject.sdk.server.auth.TaskAuthorizationProvider;
+ * import org.a2aproject.sdk.server.auth.TaskOperation;
+ *
  * @ApplicationScoped
  * public class MyTaskAuthorizationProvider implements TaskAuthorizationProvider {
+ *     private final ConcurrentMap ownershipStore = new ConcurrentHashMap<>();
  *
  *     @Override
  *     public boolean checkRead(ServerCallContext context, String taskId, TaskOperation op) {
- *         User user = context.getUser();
- *         // look up ownership in your backing store
- *         return isOwner(user, taskId);
+ *         return isOwner(context, taskId);
+ *     }
+ *
+ *     private boolean isOwner(ServerCallContext context, String taskId) {
+ *         String owner = ownershipStore.get(taskId);
+ *         return owner != null
+ *                 && context.getUser() != null
+ *                 && owner.equals(context.getUser().getUsername());
  *     }
  *
  *     @Override
  *     public boolean checkWrite(ServerCallContext context, String taskId, TaskOperation op) {
- *         return checkRead(context, taskId, op); // same rule
+ *         return isOwner(context, taskId);
  *     }
  *
  *     @Override
  *     public boolean checkCreate(ServerCallContext context, TaskOperation op) {
- *         return context.getUser().isAuthenticated();
+ *         return context.getUser() != null && context.getUser().isAuthenticated();
  *     }
  *
  *     @Override
  *     public boolean isTaskRecorded(String taskId) {
- *         return ownershipStore.contains(taskId);
+ *         return ownershipStore.containsKey(taskId);
  *     }
  *
  *     @Override
  *     public void recordOwnership(ServerCallContext context, String taskId, TaskOperation op) {
- *         ownershipStore.put(taskId, context.getUser().getUsername());
+ *         if (context.getUser() != null) {
+ *             ownershipStore.putIfAbsent(taskId, context.getUser().getUsername());
+ *         }
  *     }
  * }
  * }