A showcase project demonstrates:
- using act-aaa with database storage
- an integrated development environment for API management and automate testing
The requirement of the bookmark project has been defined in github. It is recommend the new comer to read through the requirements which links to the implementation and automate testing of the project.
The first time user can load the project into IDE (Intellij IDEA preferred) and view the structure of the project. Once the project is loaded into IDE, the user can run the project by run the main entry class: demo.AppEntry
:
Once the app has been started (in dev mode), the developer can get access to the API document by visiting ~/api
:
Note API document is generated automatically by ActFramework. Developer just need to put the right information in Javadoc in the source code. The corresponding Javadoc for the endpoint shown in the above screenshot is:
As shown above, ActFramework automatically generates sample data for endpoints.
The bookmark project has been created with full automate testing scenarios which covers all stories defined, including the normal and exceptional cases. The testing scenarios are defined in src/main/resources/test/scenarios
dir:
When app has been started in dev mode, the developer can run automate test by going to ~/test
:
In this project we have demonstrated how to create permission/role/privilege model class that can be mapped into database. There is no database schema needs to be defined and imported before running the project though. The framework generates database from the model class at it's first run. However if one do need the schema for the AAA objects (Permission/Role/Privilege), here is the SQL create table scripts:
CREATE TABLE "PUBLIC"."PERM"
(
ID integer PRIMARY KEY NOT NULL,
DYNAMIC boolean,
NAME varchar(2147483647)
)
;
CREATE UNIQUE INDEX PRIMARY_KEY_256 ON "PUBLIC"."PERM"(ID)
;
CREATE TABLE "PUBLIC"."PRIV"
(
ID integer PRIMARY KEY NOT NULL,
LEVEL integer,
NAME varchar(2147483647)
)
;
CREATE UNIQUE INDEX PRIMARY_KEY_25 ON "PUBLIC"."PRIV"(ID)
;
CREATE TABLE "PUBLIC"."ROLE"
(
ID integer PRIMARY KEY NOT NULL,
NAME varchar(2147483647),
PERMS varchar(2147483647)
)
;
CREATE UNIQUE INDEX PRIMARY_KEY_26 ON "PUBLIC"."ROLE"(ID)
;
Once act-aaa
has been added into the project pom dependencies, all endpoints are by default require authentication, meaning if a user that hasn't logged in request to an endpoint, a 401 response will be send back.
In order to mark an endpoint as public, i.e. no authentication required, it can add NoAuthentication
annotation to the controller class or request handler method, e.g.
package demo.service;
import act.controller.Controller;
import act.controller.annotation.UrlContext;
import org.osgl.aaa.NoAuthentication;
@NoAuthentication
@UrlContext("/api/v1")
public abstract class PublicServiceBase extends Controller.Util {
}
The above code define a base class for public controllers, all request handler method defined in the sub class of PublicServiceBase
will not require authentication
Whenever a resource needs authorisation protection, the developer can use AAA.requirePermission(...)
APIs to declare an authorisation requirement to protect the resource, e.g.
@PostAction
@PropertySpec("id")
public Bookmark create(@Valid Bookmark bookmark) {
AAA.requirePermission(AppPermission.PERM_CREATE_BOOKMARK);
bookmark.owner = me.email;
return bookmarkDao.save(bookmark);
}
The above code declare permission AppPermission.PERM_CREATE_BOOKMARK
is required to access create bookmark endpoint.
It is not unusual that a resource protected by authorisation needs to do further check besides permission check. e.g.
@PutAction("{bookmark}")
public void update(@DbBind @NotNull Bookmark bookmark, @NotBlank String description) {
AAA.requirePermission(bookmark, AppPermission.PERM_EDIT_MY_BOOKMARK);
bookmark.description = description;
bookmarkDao.save(bookmark);
}
The above code declare permission PERM_EDIT_MY_BOOKMARK
is required to edit a bookmark, however, it doesn't make sense to let user A to edit a bookmark created by user B, thus we have declared PERM_EDIT_MY_BOOKMARK
permission in AppPermission.java
as dynamic permission, meaning aaa framework needs to further check if the resource been protected (the bookmark
here) is owned by (linked to) the current user. The link between bookmark and user is implemented in Bookmark
class:
@Entity(name = "bookmark")
public class Bookmark implements UserLinked {
...
@Override
public boolean isLinkedTo(Principal principal) {
return S.eq(principal.getName(), owner);
}
...
}