@@ -299,14 +299,15 @@ public class ApiConstants { | |||
public static final String API_TAG_ACCOUNT_OBJECTS = "account-owned objects"; | |||
public static final String API_TAG_APPS = "bubble apps"; | |||
public static final String API_TAG_DEVICES = "devices"; | |||
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_CLOUDS = "clouds"; | |||
public static final String API_TAG_DEBUG = "debug"; | |||
public static final String API_TAG_MITMPROXY = "mitmproxy"; | |||
public static final String API_TAG_APP_RUNTIME = "bubble app runtime"; | |||
public static final String API_TAG_NODE = "node"; | |||
public static final String API_TAG_NODE_MANAGER = "node manager"; | |||
public static final String API_TAG_PAYMENT = "payment"; | |||
public static final String API_TAG_SEARCH = "search"; | |||
public static String getToken(String json) { | |||
if (json == null) return null; | |||
@@ -30,21 +30,25 @@ import javax.ws.rs.*; | |||
import javax.ws.rs.core.Context; | |||
import javax.ws.rs.core.Response; | |||
import java.io.IOException; | |||
import java.util.*; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Map; | |||
import java.util.TreeSet; | |||
import java.util.function.Predicate; | |||
import java.util.stream.Collectors; | |||
import static bubble.ApiConstants.API_TAG_DEBUG; | |||
import static bubble.ApiConstants.DEBUG_ENDPOINT; | |||
import static bubble.cloud.auth.RenderedMessage.filteredInbox; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.die; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | |||
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_SERVER_ERROR; | |||
import static org.cobbzilla.util.json.JsonUtil.*; | |||
import static org.cobbzilla.util.reflect.ReflectionUtil.forName; | |||
import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | |||
import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.API_TAG_UTILITY; | |||
@Consumes(APPLICATION_JSON) | |||
@Produces(APPLICATION_JSON) | |||
@@ -55,7 +59,7 @@ public class DebugResource { | |||
@Autowired private BubbleConfiguration configuration; | |||
@GET @Path("/inbox/{type}/{recipient}") | |||
@Operation(tags=API_TAG_UTILITY, | |||
@Operation(tags=API_TAG_DEBUG, | |||
summary="Read debug mailboxes", | |||
description="Read debug mailboxes. Must be admin. These are only used in testing.", | |||
responses=@ApiResponse(responseCode=SC_OK, description="a JSON array of RenderedMessage") | |||
@@ -100,6 +104,11 @@ public class DebugResource { | |||
} | |||
@GET @Path("/error") | |||
@Operation(tags=API_TAG_DEBUG, | |||
summary="Generate an error", | |||
description="Generate an error", | |||
responses=@ApiResponse(responseCode=SC_SERVER_ERROR, description="an error") | |||
) | |||
public Response testError(@Context ContainerRequest ctx, | |||
@QueryParam("type") String type, | |||
@QueryParam("message") String message) { | |||
@@ -115,6 +124,11 @@ public class DebugResource { | |||
} | |||
@GET @Path("/beans") | |||
@Operation(tags=API_TAG_DEBUG, | |||
summary="List Spring beans", | |||
description="List Spring beans", | |||
responses=@ApiResponse(responseCode=SC_OK, description="array of bean names") | |||
) | |||
public Response springBeans(@Context ContainerRequest ctx, | |||
@QueryParam("type") String type) { | |||
final ApplicationContext spring = configuration.getApplicationContext(); | |||
@@ -132,6 +146,11 @@ public class DebugResource { | |||
} | |||
@POST @Path("/echo") | |||
@Operation(tags=API_TAG_DEBUG, | |||
summary="Echo JSON to log", | |||
description="Echo JSON to log", | |||
responses=@ApiResponse(responseCode=SC_OK, description="some JSON") | |||
) | |||
public Response echoJsonInLog(@Context ContainerRequest ctx, | |||
@Valid @NonNull final JsonNode input, | |||
@QueryParam("respondWith") @Nullable final String respondWith) throws IOException { | |||
@@ -48,6 +48,7 @@ import static bubble.ApiConstants.*; | |||
import static bubble.model.account.Account.ROOT_EMAIL; | |||
import static bubble.model.cloud.BubbleNetwork.validateHostname; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_NOT_FOUND; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.util.string.ValidationRegexes.*; | |||
import static org.cobbzilla.wizard.model.NamedEntity.NAME_MAXLEN; | |||
@@ -374,6 +375,16 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco | |||
} | |||
@GET @Path("/{id}"+EP_PAYMENT_METHOD) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_PAYMENT, | |||
summary="Get payment method for plan", | |||
description="Get the AccountPaymentMethod associated with the Account Plan", | |||
parameters=@Parameter(name="id", description="UUID or name of AccountPlan"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="an AccountPaymentMethod object"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="account plan not found") | |||
} | |||
) | |||
public Response getPaymentMethod(@Context ContainerRequest ctx, | |||
@PathParam("id") String id) { | |||
final AccountPlan accountPlan = find(ctx, id); | |||
@@ -384,6 +395,16 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco | |||
} | |||
@GET @Path("/{id}"+EP_PLAN) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_ACCOUNT, | |||
summary="Get Bubble Plan", | |||
description="Get Bubble Plan for Account Plan", | |||
parameters=@Parameter(name="id", description="UUID or name of AccountPlan"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a BubblePlan object"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="account plan not found") | |||
} | |||
) | |||
public Response getBubblePlan(@Context ContainerRequest ctx, | |||
@PathParam("id") String id) { | |||
final AccountPlan accountPlan = find(ctx, id); | |||
@@ -182,6 +182,7 @@ public class NetworksResource extends AccountOwnedResource<BubbleNetwork, Bubble | |||
@Path("/{id}"+EP_TAGS) | |||
@Operation(hidden=true) | |||
public TagsResource getTags(@Context ContainerRequest ctx, | |||
@PathParam("id") String id) { | |||
final BubbleNetwork network = find(ctx, id); | |||
@@ -13,6 +13,8 @@ import bubble.resources.account.VpnConfigResource; | |||
import bubble.server.BubbleConfiguration; | |||
import bubble.service.device.DeviceService; | |||
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.extern.slf4j.Slf4j; | |||
import org.glassfish.grizzly.http.server.Request; | |||
@@ -31,6 +33,8 @@ import java.util.stream.Collectors; | |||
import static bubble.ApiConstants.*; | |||
import static bubble.model.device.DeviceStatusFirstComparator.DEVICE_WITH_STATUS_FIRST; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_NOT_FOUND; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | |||
import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.SEC_API_KEY; | |||
@@ -98,10 +102,22 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> { | |||
} | |||
@POST @Path("/{id}"+EP_SECURITY_LEVEL+"/{level}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
public Response getIps(@Context ContainerRequest ctx, | |||
@PathParam("id") String id, | |||
@PathParam("level") DeviceSecurityLevel level) { | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_DEVICES, | |||
summary="Set security level", | |||
description="Set security level for device. Levels are: `maximum`, `strict`, `standard`, `basic`, `disabled`", | |||
parameters={ | |||
@Parameter(name="id", description="device UUID or name"), | |||
@Parameter(name="level", description="security level. Levels are: `maximum`, `strict`, `standard`, `basic`, `disabled`") | |||
}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="array of IP addresses for device"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="device not found") | |||
} | |||
) | |||
public Response setSecurityLevel(@Context ContainerRequest ctx, | |||
@PathParam("id") String id, | |||
@PathParam("level") DeviceSecurityLevel level) { | |||
final Device device = getDao().findByAccountAndId(getAccountUuid(ctx), id); | |||
if (device == null) return notFound(id); | |||
return ok(getDao().update(device.setSecurityLevel(level))); | |||
@@ -117,7 +133,16 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> { | |||
@Autowired private DeviceService deviceService; | |||
@GET @Path("/{id}"+EP_IPS) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_DEVICES, | |||
summary="Get IP addresses for device", | |||
description="Get IP addresses for device", | |||
parameters=@Parameter(name="id", description="device UUID or name"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="array of IP addresses for device"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="device not found") | |||
} | |||
) | |||
public Response getIps(@Context ContainerRequest ctx, | |||
@PathParam("id") String id) { | |||
final Device device = getDao().findByAccountAndId(getAccountUuid(ctx), id); | |||
@@ -126,8 +151,17 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> { | |||
} | |||
@GET @Path("/{id}"+EP_STATUS) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
public Response getStatus(@Context ContainerRequest ctx, | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_DEVICES, | |||
summary="Get device status", | |||
description="Get device status", | |||
parameters=@Parameter(name="id", description="device UUID or name"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a DeviceStatus object"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="device not found") | |||
} | |||
) | |||
public Response getStatus(@Context ContainerRequest ctx, | |||
@PathParam("id") String id) { | |||
final Device device = getDao().findByAccountAndId(getAccountUuid(ctx), id); | |||
if (device == null) return notFound(id); | |||