Browse Source

WIP. adding more openapi docs

tags/v1.4.37
Jonathan Cobb 3 years ago
parent
commit
4ac87f263e
6 changed files with 87 additions and 18 deletions
  1. +1
    -0
      bubble-server/src/main/java/bubble/ApiConstants.java
  2. +2
    -1
      bubble-server/src/main/java/bubble/model/account/TrustedClientResponse.java
  3. +6
    -6
      bubble-server/src/main/java/bubble/resources/account/AuthResource.java
  4. +4
    -4
      bubble-server/src/main/java/bubble/resources/account/MeResource.java
  5. +35
    -3
      bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java
  6. +39
    -4
      bubble-server/src/main/java/bubble/resources/account/VpnConfigResource.java

+ 1
- 0
bubble-server/src/main/java/bubble/ApiConstants.java View File

@@ -297,6 +297,7 @@ public class ApiConstants {
public static final String API_TAG_AUTH = "auth";
public static final String API_TAG_ACCOUNT = "account";
public static final String API_TAG_ACCOUNT_OBJECTS = "account-owned objects";
public static final String API_TAG_DEVICE = "device";
public static final String API_TAG_SEARCH = "search";
public static final String API_TAG_BACKUP_RESTORE = "backup and restore";
public static final String API_TAG_NODE = "node";


+ 2
- 1
bubble-server/src/main/java/bubble/model/account/TrustedClientResponse.java View File

@@ -8,8 +8,9 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.cobbzilla.wizard.model.OpenApiSchema;

@NoArgsConstructor @AllArgsConstructor
@NoArgsConstructor @AllArgsConstructor @OpenApiSchema
public class TrustedClientResponse {

@Getter @Setter private String id;


+ 6
- 6
bubble-server/src/main/java/bubble/resources/account/AuthResource.java View File

@@ -143,8 +143,8 @@ public class AuthResource {

@GET @Path(EP_READY)
@Operation(tags=API_TAG_UTILITY,
summary="Determine if the API is running and ready for login",
description="Determine if the API is running and ready for login",
summary="Determine if Bubble is running and ready for login",
description="Determine if Bubble is running and ready for login",
responses={
@ApiResponse(responseCode=SC_OK, description="empty response with status 200 if API is ready"),
@ApiResponse(responseCode=SC_INVALID, description="error with status 422 if API is NOT ready")
@@ -168,8 +168,8 @@ public class AuthResource {

@GET @Path(EP_ACTIVATE)
@Operation(tags=API_TAG_ACTIVATION,
summary="Determine if the API has been activated",
description="Determine if the API has been activated",
summary="Determine if Bubble has been activated",
description="Determine if Bubble has been activated",
responses={
@ApiResponse(responseCode=SC_OK, description="returns true if API is activated, false otherwise",
content=@Content(mediaType=APPLICATION_JSON, examples={
@@ -1021,7 +1021,7 @@ public class AuthResource {

@GET @Path(EP_SUPPORT+"/{locale}")
@Operation(tags=API_TAG_UTILITY,
summary="Get support information",
summary="Get support information for a locale",
description="Get support information for the given locale, if available. Use the default locale otherwise.",
parameters=@Parameter(name="locale", description="locale to find support for"),
responses=@ApiResponse(responseCode=SC_OK, description="SupportInfo object")
@@ -1046,7 +1046,7 @@ public class AuthResource {

@GET @Path(EP_APP_LINKS+"/{locale}")
@Operation(tags=API_TAG_UTILITY,
summary="Get links to native applications",
summary="Get links to native applications for a locale",
description="Get links to native applications for the given locale, if available. Use the default locale otherwise.",
parameters=@Parameter(name="locale", description="locale to find app links for"),
responses=@ApiResponse(responseCode=SC_OK, description="AppLinks object")


+ 4
- 4
bubble-server/src/main/java/bubble/resources/account/MeResource.java View File

@@ -126,8 +126,8 @@ public class MeResource {
@GET @Path(EP_LOCALE)
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_ACCOUNT,
summary="Get the account locale",
description="Get the account locale",
summary="Get the locale for the current user",
description="Get the locale for the current user",
responses=@ApiResponse(responseCode=SC_OK, description="Locale string", content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="default locale", value="en_US")))
)
public Response getLocale(@Context ContainerRequest ctx) {
@@ -138,8 +138,8 @@ public class MeResource {
@POST @Path(EP_LOCALE+"/{locale}")
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_ACCOUNT,
summary="Set the account locale",
description="Set the account locale",
summary="Set the locale for the current user",
description="Set the locale for the current user",
responses=@ApiResponse(responseCode=SC_OK, description="updated Account object")
)
public Response setLocale(@Context ContainerRequest ctx,


+ 35
- 3
bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java View File

@@ -14,6 +14,8 @@ import bubble.model.account.message.ActionTarget;
import bubble.model.device.Device;
import bubble.service.account.StandardAuthenticatorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -26,12 +28,13 @@ import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import static bubble.ApiConstants.EP_DELETE;
import static bubble.ApiConstants.*;
import static bubble.resources.account.AuthResource.newLoginSession;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.daemon.ZillaRuntime.now;
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON;
import static org.cobbzilla.util.http.HttpStatusCodes.*;
import static org.cobbzilla.wizard.cache.redis.RedisService.PX;
import static org.cobbzilla.wizard.resources.ResourceUtil.*;
import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.SEC_API_KEY;
@@ -54,7 +57,16 @@ public class TrustedAuthResource {
@Getter(lazy=true) private final RedisService trustHashCache = redis.prefixNamespace("loginTrustedClient");

@PUT
@Operation(security=@SecurityRequirement(name=SEC_API_KEY))
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Establish trust with a device",
description="Establish trust with a device. Returns a TrustedClientResponse with an id that can be used for future logins",
responses={
@ApiResponse(responseCode=SC_OK, description="TrustedClientResponse object"),
@ApiResponse(responseCode=SC_NOT_FOUND, description="if the email/password login was incorrect"),
@ApiResponse(responseCode=SC_INVALID, description="validation error. for example: TOTP required, or the device is already trusted")
}
)
public Response trustClient(@Context ContainerRequest ctx,
AccountLoginRequest request) {
final Account caller = userPrincipal(ctx);
@@ -78,6 +90,16 @@ public class TrustedAuthResource {
}

@POST
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Login as a trusted client",
description="Login as a trusted client. Starts a new API session",
responses={
@ApiResponse(responseCode=SC_OK, description="Account object with session token"),
@ApiResponse(responseCode=SC_NOT_FOUND, description="if the email/password login was incorrect"),
@ApiResponse(responseCode=SC_INVALID, description="validation error. for example: TOTP required, or the device is already trusted")
}
)
public Response loginTrustedClient(@Context ContainerRequest ctx,
@Valid TrustedClientLoginRequest request) {
final Account account = validateTrustedCall(request);
@@ -92,7 +114,17 @@ public class TrustedAuthResource {
}

@DELETE @Path(EP_DELETE+"/{device}")
@Operation(security=@SecurityRequirement(name=SEC_API_KEY))
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Remove trust from a trusted client",
description="Remove trust from a trusted client",
parameters=@Parameter(name="device", description="uuid of the device"),
responses={
@ApiResponse(responseCode=SC_OK, description="Account object with session token"),
@ApiResponse(responseCode=SC_NOT_FOUND, description="if the email/password login was incorrect"),
@ApiResponse(responseCode=SC_INVALID, description="validation error. for example: TOTP required, or the device is already trusted")
}
)
public Response removeTrustedClient(@Context ContainerRequest ctx,
@PathParam("device") String deviceId) {
final Account caller = userPrincipal(ctx);


+ 39
- 4
bubble-server/src/main/java/bubble/resources/account/VpnConfigResource.java View File

@@ -7,6 +7,7 @@ package bubble.resources.account;
import bubble.model.account.Account;
import bubble.model.device.Device;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.io.FileUtil;
@@ -23,7 +24,9 @@ import javax.ws.rs.core.Response;
import java.io.File;
import java.io.IOException;

import static bubble.ApiConstants.API_TAG_DEVICE;
import static org.cobbzilla.util.http.HttpContentTypes.*;
import static org.cobbzilla.util.http.HttpStatusCodes.*;
import static org.cobbzilla.util.io.FileUtil.abs;
import static org.cobbzilla.wizard.resources.ResourceUtil.*;
import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.SEC_API_KEY;
@@ -58,7 +61,15 @@ public class VpnConfigResource {

@GET @Path("/QR.png")
@Produces(IMAGE_PNG)
@Operation(security=@SecurityRequirement(name=SEC_API_KEY))
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Get QR code PNG image for device",
description="Get QR code PNG image for device",
responses={
@ApiResponse(responseCode=SC_OK, description="QR code PNG image data"),
@ApiResponse(responseCode=SC_FORBIDDEN, description="if caller is not admin or does not own the device")
}
)
public Response qrCode(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
if (!caller.admin() && !caller.getUuid().equals(device.getAccount())) return forbidden();
@@ -67,7 +78,15 @@ public class VpnConfigResource {

@GET @Path("/QR.png.base64")
@Produces(TEXT_PLAIN)
@Operation(security=@SecurityRequirement(name=SEC_API_KEY))
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Get QR code PNG image, as Base64-encoded string",
description="Get QR code PNG image, as Base64-encoded string",
responses={
@ApiResponse(responseCode=SC_OK, description="Base64-encoded QR code PNG image data"),
@ApiResponse(responseCode=SC_FORBIDDEN, description="if caller is not admin or does not own the device")
}
)
public Response qrCodeBase64(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
if (!caller.admin() && !caller.getUuid().equals(device.getAccount())) return forbidden();
@@ -82,7 +101,15 @@ public class VpnConfigResource {

@GET @Path("/vpn.conf")
@Produces(APPLICATION_OCTET_STREAM)
@Operation(security=@SecurityRequirement(name=SEC_API_KEY))
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Get WireGuard vpn.conf file for device",
description="Get WireGuard vpn.conf file for device",
responses={
@ApiResponse(responseCode=SC_OK, description="vpn.conf file data"),
@ApiResponse(responseCode=SC_FORBIDDEN, description="if caller is not admin or does not own the device")
}
)
public Response confFile(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
if (!caller.admin() && !caller.getUuid().equals(device.getAccount())) return forbidden();
@@ -95,7 +122,15 @@ public class VpnConfigResource {

@GET @Path("/vpn.conf.base64")
@Produces(TEXT_PLAIN)
@Operation(security=@SecurityRequirement(name=SEC_API_KEY))
@Operation(security=@SecurityRequirement(name=SEC_API_KEY),
tags=API_TAG_DEVICE,
summary="Get WireGuard vpn.conf file, as Base64-encoded string",
description="Get WireGuard vpn.conf file for device, as Base64-encoded string",
responses={
@ApiResponse(responseCode=SC_OK, description="Base64-encoded vpn.conf file data"),
@ApiResponse(responseCode=SC_FORBIDDEN, description="if caller is not admin or does not own the device")
}
)
public Response confFileBase64(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
if (!caller.admin() && !caller.getUuid().equals(device.getAccount())) return forbidden();


Loading…
Cancel
Save