@@ -301,6 +301,7 @@ public class ApiConstants { | |||
public static final String API_TAG_BACKUP_RESTORE = "backup and restore"; | |||
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 String getToken(String json) { | |||
if (json == null) return null; | |||
@@ -10,6 +10,8 @@ import lombok.NoArgsConstructor; | |||
import lombok.Setter; | |||
import lombok.experimental.Accessors; | |||
import org.cobbzilla.mail.SimpleEmailMessage; | |||
import org.cobbzilla.wizard.model.OpenApiSchema; | |||
import org.cobbzilla.wizard.model.entityconfig.annotations.ECField; | |||
import java.util.Map; | |||
@@ -17,11 +19,11 @@ import static java.util.UUID.randomUUID; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.now; | |||
import static org.cobbzilla.util.reflect.ReflectionUtil.copy; | |||
@NoArgsConstructor @Accessors(chain=true) | |||
@NoArgsConstructor @Accessors(chain=true) @OpenApiSchema | |||
public class RenderedEmail extends SimpleEmailMessage implements RenderedMessage { | |||
@Getter private final long ctime = now(); | |||
@Getter private final String uuid = randomUUID().toString(); | |||
@ECField @Getter private final long ctime = now(); | |||
@ECField @Getter private final String uuid = randomUUID().toString(); | |||
@Getter @Setter private Map<String, Object> ctx; | |||
public RenderedEmail (Map<String, Object> ctx) { this.ctx = ctx; } | |||
@@ -10,16 +10,19 @@ import lombok.Getter; | |||
import lombok.NoArgsConstructor; | |||
import lombok.Setter; | |||
import lombok.experimental.Accessors; | |||
import org.cobbzilla.wizard.model.OpenApiSchema; | |||
import org.cobbzilla.wizard.model.entityconfig.EntityFieldType; | |||
import org.cobbzilla.wizard.model.entityconfig.annotations.ECField; | |||
import javax.persistence.Transient; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.big; | |||
@NoArgsConstructor @AllArgsConstructor @Accessors(chain=true) | |||
@NoArgsConstructor @AllArgsConstructor @Accessors(chain=true) @OpenApiSchema | |||
public class GeoCodeResult { | |||
@Getter @Setter private String lat; | |||
@Getter @Setter private String lon; | |||
@ECField(type=EntityFieldType.decimal) @Getter @Setter private String lat; | |||
@ECField(type=EntityFieldType.decimal) @Getter @Setter private String lon; | |||
@JsonIgnore @Transient public double getLatitude () { return big(lat).doubleValue(); } | |||
@JsonIgnore @Transient public double getLongitude () { return big(lon).doubleValue(); } | |||
@@ -12,12 +12,15 @@ import lombok.Setter; | |||
import lombok.ToString; | |||
import lombok.experimental.Accessors; | |||
import org.cobbzilla.util.math.Haversine; | |||
import org.cobbzilla.wizard.model.OpenApiSchema; | |||
import org.cobbzilla.wizard.model.entityconfig.EntityFieldType; | |||
import org.cobbzilla.wizard.model.entityconfig.annotations.ECField; | |||
import javax.persistence.Transient; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | |||
@NoArgsConstructor @Accessors(chain=true) @ToString(of={"lat", "lon"}) | |||
@NoArgsConstructor @Accessors(chain=true) @ToString(of={"lat", "lon"}) @OpenApiSchema | |||
public class GeoLocation { | |||
public static final GeoLocation NULL_LOCATION = new GeoLocation().setLat("-1.0").setLon("-1.0"); | |||
@@ -27,8 +30,8 @@ public class GeoLocation { | |||
@Getter @Setter private String region; | |||
@Getter @Setter private String city; | |||
@Getter @Setter private String lat; | |||
@Getter @Setter private String lon; | |||
@ECField(type=EntityFieldType.decimal) @Getter @Setter private String lat; | |||
@ECField(type=EntityFieldType.decimal) @Getter @Setter private String lon; | |||
@JsonIgnore @Transient public double getLatitude () { return big(lat).doubleValue(); } | |||
@JsonIgnore @Transient public double getLongitude () { return big(lon).doubleValue(); } | |||
@@ -9,8 +9,9 @@ import lombok.Getter; | |||
import lombok.NoArgsConstructor; | |||
import lombok.Setter; | |||
import lombok.experimental.Accessors; | |||
import org.cobbzilla.wizard.model.OpenApiSchema; | |||
@NoArgsConstructor @AllArgsConstructor @Accessors(chain=true) | |||
@NoArgsConstructor @AllArgsConstructor @Accessors(chain=true) @OpenApiSchema | |||
public class GeoTimeZone { | |||
public static final GeoTimeZone UTC = new GeoTimeZone("Etc/UTC", "UTC", 0L); | |||
@@ -5,14 +5,14 @@ | |||
package bubble.model; | |||
import com.fasterxml.jackson.annotation.JsonIgnore; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
import org.cobbzilla.wizard.model.OpenApiSchema; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
@Schema | |||
@OpenApiSchema | |||
public class AppLinks extends BasicAppLinks { | |||
@JsonIgnore @Getter @Setter private Map<String, BasicAppLinks> locale = new HashMap<>(); | |||
@@ -8,12 +8,14 @@ import lombok.Getter; | |||
import lombok.Setter; | |||
import org.cobbzilla.wizard.model.entityconfig.annotations.ECField; | |||
import static org.cobbzilla.wizard.model.entityconfig.EntityFieldType.http_url; | |||
public class BasicAppLinks { | |||
@ECField @Getter @Setter private String ios; | |||
@ECField @Getter @Setter private String android; | |||
@ECField @Getter @Setter private String windows; | |||
@ECField @Getter @Setter private String macosx; | |||
@ECField @Getter @Setter private String linux; | |||
@ECField(type=http_url) @Getter @Setter private String ios; | |||
@ECField(type=http_url) @Getter @Setter private String android; | |||
@ECField(type=http_url) @Getter @Setter private String windows; | |||
@ECField(type=http_url) @Getter @Setter private String macosx; | |||
@ECField(type=http_url) @Getter @Setter private String linux; | |||
} |
@@ -7,7 +7,6 @@ package bubble.model.cloud; | |||
import bubble.model.account.Account; | |||
import bubble.model.account.HasAccountNoName; | |||
import com.fasterxml.jackson.annotation.JsonIgnore; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
import lombok.Getter; | |||
import lombok.NoArgsConstructor; | |||
import lombok.Setter; | |||
@@ -37,7 +36,7 @@ import static org.cobbzilla.util.security.ShaUtil.sha256_hex; | |||
import static org.cobbzilla.wizard.model.crypto.EncryptedTypes.ENCRYPTED_STRING; | |||
import static org.cobbzilla.wizard.model.crypto.EncryptedTypes.ENC_PAD; | |||
@Entity @ECType(root=true) @ECTypeCreate(method="DISABLED") @Schema | |||
@Entity @ECType(root=true) @ECTypeCreate(method="DISABLED") | |||
@NoArgsConstructor @Accessors(chain=true) @ToString(of={"publicKeyHash"}, callSuper=true) | |||
public class BubbleNodeKey extends IdentifiableBase implements HasAccountNoName { | |||
@@ -4,6 +4,8 @@ | |||
*/ | |||
package bubble.resources; | |||
import io.swagger.v3.oas.annotations.Operation; | |||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.glassfish.jersey.server.ContainerRequest; | |||
import org.springframework.stereotype.Service; | |||
@@ -17,7 +19,9 @@ import javax.ws.rs.core.Response; | |||
import static bubble.ApiConstants.BUBBLE_MAGIC_ENDPOINT; | |||
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.ok; | |||
import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.API_TAG_UTILITY; | |||
@Consumes(APPLICATION_JSON) | |||
@Produces(APPLICATION_JSON) | |||
@@ -26,6 +30,11 @@ import static org.cobbzilla.wizard.resources.ResourceUtil.ok; | |||
public class BubbleMagicResource { | |||
@GET | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Simple health check", | |||
description="Returns a static string, verifies that API can communicate over the network", | |||
responses=@ApiResponse(responseCode=SC_OK, description="fixed response") | |||
) | |||
public Response get(@Context ContainerRequest ctx) { | |||
return ok("you are ok. the magic is ok too."); | |||
} | |||
@@ -14,6 +14,8 @@ import bubble.model.account.message.AccountMessageType; | |||
import bubble.model.account.message.ActionTarget; | |||
import bubble.server.BubbleConfiguration; | |||
import com.fasterxml.jackson.databind.JsonNode; | |||
import io.swagger.v3.oas.annotations.Operation; | |||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||
import lombok.NonNull; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.glassfish.jersey.server.ContainerRequest; | |||
@@ -37,10 +39,12 @@ 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.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) | |||
@@ -51,6 +55,11 @@ public class DebugResource { | |||
@Autowired private BubbleConfiguration configuration; | |||
@GET @Path("/inbox/{type}/{recipient}") | |||
@Operation(tags=API_TAG_UTILITY, | |||
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") | |||
) | |||
public Response inbox(@Context ContainerRequest ctx, | |||
@PathParam("type") CloudServiceType type, | |||
@PathParam("recipient") String recipient, | |||
@@ -4,8 +4,9 @@ | |||
*/ | |||
package bubble.resources; | |||
import bubble.cloud.CloudServiceType; | |||
import bubble.service.cloud.GeoService; | |||
import io.swagger.v3.oas.annotations.Operation; | |||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.glassfish.grizzly.http.server.Request; | |||
import org.glassfish.jersey.server.ContainerRequest; | |||
@@ -21,7 +22,10 @@ import javax.ws.rs.core.Response; | |||
import static bubble.ApiConstants.*; | |||
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.ok; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.optionalUserPrincipal; | |||
import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.API_TAG_UTILITY; | |||
@Consumes(APPLICATION_JSON) | |||
@Produces(APPLICATION_JSON) | |||
@@ -32,12 +36,22 @@ public class DetectResource { | |||
@Autowired private GeoService geoService; | |||
@GET @Path(EP_LOCALE) | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Detect the caller's locale", | |||
description="Detect the caller's locale", | |||
responses=@ApiResponse(responseCode=SC_OK, description="an array of locale strings in priority order") | |||
) | |||
public Response detectLocales(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
return ok(geoService.getSupportedLocales(optionalUserPrincipal(ctx), getRemoteHost(req), normalizeLangHeader(req))); | |||
} | |||
@GET @Path(EP_TIMEZONE) | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Detect the caller's time zone", | |||
description="Detect the caller's time zone", | |||
responses=@ApiResponse(responseCode=SC_OK, description="the TimeZone ") | |||
) | |||
public Response detectTimezone(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
return ok(geoService.getTimeZone(optionalUserPrincipal(ctx), getRemoteHost(req))); | |||
@@ -53,17 +53,12 @@ public class EntityConfigsResource extends AbstractEntityConfigsResource { | |||
@POST @Path("/set/{param}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="Set a configuration parameter to `true`", | |||
description="Set a configuration parameter to `true`", | |||
parameters={@Parameter(name="param", description="the name of the parameter to set")}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the value that was set", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="should always return true", value="true") | |||
} | |||
)}) | |||
} | |||
parameters=@Parameter(name="param", description="the name of the parameter to set"), | |||
responses=@ApiResponse(responseCode=SC_OK, description="the value that was set", | |||
content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="should always return true", value="true"))) | |||
) | |||
public Response setConfig (@Context ContainerRequest ctx, | |||
@PathParam("param") String param) { | |||
@@ -72,7 +67,7 @@ public class EntityConfigsResource extends AbstractEntityConfigsResource { | |||
@POST @Path("/set/{param}/{value}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="Set a configuration parameter to a value", | |||
description="Set a configuration parameter to a value", | |||
parameters={ | |||
@@ -81,10 +76,7 @@ public class EntityConfigsResource extends AbstractEntityConfigsResource { | |||
}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the value that was set", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="if the value was the String 'foo'", value="\"foo\"") | |||
} | |||
)}) | |||
content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="if the value was the String 'foo'", value="\"foo\""))) | |||
} | |||
) | |||
public Response setConfig (@Context ContainerRequest ctx, | |||
@@ -49,19 +49,16 @@ public class IdentityResource { | |||
@GET @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="Find what object(s) an ID belongs to. Useful when you have a UUID but don't know what kind of thing it refers to, if any.", | |||
description="Searches all model objects by ID. The id parameter is typically a UUID or name", | |||
parameters={@Parameter(name="id", description="an identifier (typically UUID or name) to search for")}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a JSON object where the property names are entity types, and a property's corresponding value is the object of that type found with the given ID", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="usually a UUID only matches one object", value="{\"CloudService\": {\"uuid\": \"the-ID-you-searched-for\", \"other-cloud-service-fields\": \"would-be-shown\"}}"), | |||
@ExampleObject(name="a UUID for an Account also matches the AccountPolicy", value="{\"Account\": {\"uuid\": \"the-ID-you-searched-for\", \"other-account-fields\": \"would-be-shown\"}, \"AccountPolicy\": {\"uuid\": \"the-ID-you-searched-for\", \"other-policy-fields\": \"would-be-shown\"}}"), | |||
@ExampleObject(name="empty JSON object when no matches are found", value="{}") | |||
} | |||
)}) | |||
} | |||
parameters=@Parameter(name="id", description="an identifier (typically UUID or name) to search for"), | |||
responses=@ApiResponse(responseCode=SC_OK, description="a JSON object where the property names are entity types, and a property's corresponding value is the object of that type found with the given ID", | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="usually a UUID only matches one object", value="{\"CloudService\": {\"uuid\": \"the-ID-you-searched-for\", \"other-cloud-service-fields\": \"would-be-shown\"}}"), | |||
@ExampleObject(name="a UUID for an Account also matches the AccountPolicy", value="{\"Account\": {\"uuid\": \"the-ID-you-searched-for\", \"other-account-fields\": \"would-be-shown\"}, \"AccountPolicy\": {\"uuid\": \"the-ID-you-searched-for\", \"other-policy-fields\": \"would-be-shown\"}}"), | |||
@ExampleObject(name="empty JSON object when no matches are found", value="{}") | |||
})) | |||
) | |||
public Response identify(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -38,7 +38,7 @@ public class SearchResource { | |||
@GET @Path("/{type}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_SEARCH}, | |||
tags=API_TAG_SEARCH, | |||
summary="Search model objects", | |||
description="Search model objects", | |||
parameters={ | |||
@@ -50,9 +50,7 @@ public class SearchResource { | |||
@Parameter(name=Q_SIZE, description="page size. default is 10, max is 50"), | |||
@Parameter(name=Q_SORT, description="sort field. prefix with + or - to indicate ascending/descending") | |||
}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a SearchResults object, or if meta was true then a SqlViewField[] array") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="a SearchResults object, or if meta was true then a SqlViewField[] array") | |||
) | |||
public Response search(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -68,7 +66,7 @@ public class SearchResource { | |||
@POST @Path("/{type}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_SEARCH}, | |||
tags=API_TAG_SEARCH, | |||
summary="Search model objects", | |||
description="Search model objects", | |||
parameters={ | |||
@@ -80,9 +78,7 @@ public class SearchResource { | |||
@Parameter(name=Q_SIZE, description="page size. default is 10, max is 50"), | |||
@Parameter(name=Q_SORT, description="sort field. prefix with + or - to indicate ascending/descending") | |||
}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a SearchResults object, or if meta was true then a SqlViewField[] array") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="a SearchResults object, or if meta was true then a SqlViewField[] array") | |||
) | |||
public Response search(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -46,8 +46,8 @@ public class TagsResource { | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
summary="Set a tag", | |||
description="Set a tag", | |||
parameters={@Parameter(name="name", description="name of the tag")}, | |||
responses={@ApiResponse(responseCode=SC_OK, description="a BubbleTags object representing the current list of tags")} | |||
parameters=@Parameter(name="name", description="name of the tag"), | |||
responses=@ApiResponse(responseCode=SC_OK, description="a BubbleTags object representing the current list of tags") | |||
) | |||
public Response set(@Context ContainerRequest ctx, | |||
@PathParam("name") String name, | |||
@@ -65,10 +65,10 @@ public class AccountOwnedResource<E extends HasAccount, DAO extends AccountOwned | |||
@GET | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT_OBJECTS}, | |||
tags=API_TAG_ACCOUNT_OBJECTS, | |||
summary="List objects", | |||
description="List objects", | |||
responses={@ApiResponse(responseCode=SC_OK, description="an array of objects")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="an array of objects") | |||
) | |||
public Response listEntities(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
@@ -136,7 +136,7 @@ public class AccountOwnedResource<E extends HasAccount, DAO extends AccountOwned | |||
@GET @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT_OBJECTS}, | |||
tags=API_TAG_ACCOUNT_OBJECTS, | |||
summary="Find by identifier", | |||
description="Find by identifier", | |||
responses={ | |||
@@ -169,15 +169,13 @@ public class AccountOwnedResource<E extends HasAccount, DAO extends AccountOwned | |||
@PUT | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT_OBJECTS}, | |||
tags=API_TAG_ACCOUNT_OBJECTS, | |||
summary="Create a new object", | |||
description="Create a new object. If validation errors occur, status "+SC_INVALID+" is returned and the response will contain an array of errors. Within each error, the `messageTemplate` field refers to messages that can be localized using the /messages resource", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the object that was created"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="validation errors", value="[{\"messageTemplate\": \"some.symbolic.error\", \"message\": \"some default English message\"}]") | |||
})}) | |||
content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="validation errors", value="[{\"messageTemplate\": \"some.symbolic.error\", \"message\": \"some default English message\"}]"))) | |||
} | |||
) | |||
public Response create(@Context Request req, | |||
@@ -210,17 +208,15 @@ public class AccountOwnedResource<E extends HasAccount, DAO extends AccountOwned | |||
@POST @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT_OBJECTS}, | |||
tags=API_TAG_ACCOUNT_OBJECTS, | |||
summary="Update an existing object", | |||
description="Update an new object. For many types, the object will be created if it does not exist. If validation errors occur, status "+SC_INVALID+" is returned and the response will contain an array of errors. Within each error, the `messageTemplate` field refers to messages that can be localized using the /messages resource", | |||
parameters={@Parameter(name="id", description="the UUID (or name, if allowed) of the object to update")}, | |||
parameters=@Parameter(name="id", description="the UUID (or name, if allowed) of the object to update"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the object that was updated"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="no object exists with the given id"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="validation errors", value="[{\"messageTemplate\": \"some.symbolic.error\", \"message\": \"some default English message\"}]") | |||
})}) | |||
content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="validation errors", value="[{\"messageTemplate\": \"some.symbolic.error\", \"message\": \"some default English message\"}]"))) | |||
} | |||
) | |||
public Response update(@Context Request req, | |||
@@ -247,10 +243,10 @@ public class AccountOwnedResource<E extends HasAccount, DAO extends AccountOwned | |||
@DELETE @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT_OBJECTS}, | |||
tags=API_TAG_ACCOUNT_OBJECTS, | |||
summary="Delete an existing object", | |||
description="Delete an existing object", | |||
parameters={@Parameter(name="id", description="the UUID (or name, if allowed) of the object to delete")}, | |||
parameters=@Parameter(name="id", description="the UUID (or name, if allowed) of the object to delete"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the object that was deleted"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="no object exists with the given id") | |||
@@ -18,6 +18,7 @@ import javax.ws.rs.*; | |||
import javax.ws.rs.core.Context; | |||
import javax.ws.rs.core.Response; | |||
import static bubble.ApiConstants.API_TAG_PAYMENT; | |||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | |||
@@ -35,9 +36,10 @@ public class AccountPromotionsResource { | |||
@GET | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_PAYMENT, | |||
summary="List promotions for account", | |||
description="List promotions for account", | |||
responses={@ApiResponse(responseCode=SC_OK, description="an array of Promotion objects owned by the Account")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="an array of Promotion objects owned by the Account") | |||
) | |||
public Response listPromotions(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
@@ -48,9 +50,10 @@ public class AccountPromotionsResource { | |||
@PUT | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_PAYMENT, | |||
summary="Add a promotion to an account. Must be admin.", | |||
description="Add a promotion to an account. Must be admin.", | |||
responses={@ApiResponse(responseCode=SC_OK, description="an array of Promotion objects owned by the Account")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="an array of Promotion objects owned by the Account") | |||
) | |||
public Response adminAddPromotion(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -62,9 +65,10 @@ public class AccountPromotionsResource { | |||
@DELETE @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_PAYMENT, | |||
summary="Remove a promotion from an account. Must be admin.", | |||
description="Remove a promotion from an account. Must be admin.", | |||
responses={@ApiResponse(responseCode=SC_OK, description="an array of Promotion objects owned by the Account")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="an array of Promotion objects owned by the Account") | |||
) | |||
public Response adminRemovePromotion(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -79,7 +79,7 @@ public class AccountsResource { | |||
@GET | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="List all accounts", | |||
description="List all accounts. Must be admin.", | |||
responses={ | |||
@@ -94,7 +94,7 @@ public class AccountsResource { | |||
@GET @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Find account by UUID or email. Non-admins can only find themselves.", | |||
description="Find account by UUID or email. Non-admins can only find themselves.", | |||
responses={ | |||
@@ -110,7 +110,7 @@ public class AccountsResource { | |||
@PUT | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Create a new account", | |||
description="Create a new account. Must be admin.", | |||
responses={ | |||
@@ -173,10 +173,10 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_DOWNLOAD) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Download all data for an account", | |||
description="Download all data for user. Must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a Map<String, List<String>> of all user data"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if not admin") | |||
@@ -196,10 +196,10 @@ public class AccountsResource { | |||
@POST @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Update an account", | |||
description="Update an account. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was updated"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is updating any account Account other than themselves"), | |||
@@ -230,10 +230,10 @@ public class AccountsResource { | |||
@GET @Path("/{id}"+EP_STATUS) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="List all launch statuses for an account", | |||
description="List all launch statuses for an account. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a List<NodeProgressMeterTick> representing the status of active launch operations"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves") | |||
@@ -256,10 +256,10 @@ public class AccountsResource { | |||
@GET @Path("/{id}"+EP_POLICY) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="View the AccountPolicy for an account", | |||
description="View the AccountPolicy for an account. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="an AccountPolicy object"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves") | |||
@@ -275,10 +275,10 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_POLICY) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Update the AccountPolicy for an account", | |||
description="Update the AccountPolicy for an account. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="an AccountPolicy object"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves"), | |||
@@ -305,10 +305,10 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_POLICY+EP_CONTACTS) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Create or update an AccountContact in the AccountPolicy", | |||
description="Create or update an AccountContact in the AccountPolicy. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the AccountContact object that was created or updated"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves"), | |||
@@ -346,10 +346,10 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_POLICY+EP_CONTACTS+"/verify") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Send verification message for an AccountContact", | |||
description="Send verification message for an AccountContact. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the AccountContact object that was created or updated"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves") | |||
@@ -373,7 +373,7 @@ public class AccountsResource { | |||
@GET @Path("/{id}"+EP_POLICY+EP_CONTACTS+"/{type}/{info}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Find an AccountContact within an AccountPolicy", | |||
description="Find an AccountContact within an AccountPolicy. Caller must be the same account, or must be admin.", | |||
parameters={ | |||
@@ -400,7 +400,7 @@ public class AccountsResource { | |||
@DELETE @Path("/{id}"+EP_POLICY+EP_CONTACTS+"/{type}/{info}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Delete an AccountContact within an AccountPolicy", | |||
description="Delete an AccountContact within an AccountPolicy. Caller must be the same account, or must be admin.", | |||
parameters={ | |||
@@ -428,10 +428,10 @@ public class AccountsResource { | |||
@DELETE @Path("/{id}"+EP_POLICY+EP_CONTACTS+EP_AUTHENTICATOR) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Delete TOTP authenticator AccountContact from an AccountPolicy", | |||
description="Delete TOTP authenticator AccountContact from an AccountPolicy. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the AccountPolicy object that was updated"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves") | |||
@@ -455,7 +455,7 @@ public class AccountsResource { | |||
@DELETE @Path("/{id}"+EP_POLICY+EP_CONTACTS+"/{uuid}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Delete AccountContact from an AccountPolicy by UUID", | |||
description="Delete AccountContact from an AccountPolicy by UUID. Caller must be the same account, or must be admin.", | |||
parameters={ | |||
@@ -481,10 +481,10 @@ public class AccountsResource { | |||
@DELETE @Path("/{id}"+EP_REQUEST) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Request deletion of an Account", | |||
description="Request deletion of an Account. Caller must be the same account, or must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the AccountMessage object that was sent"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves") | |||
@@ -511,10 +511,10 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_CHANGE_PASSWORD) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Change password for an account", | |||
description="Change password for an account. Caller must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was updated"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves"), | |||
@@ -590,10 +590,10 @@ public class AccountsResource { | |||
@DELETE @Path("/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Delete an Account", | |||
description="Delete an Account. Caller must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was deleted"), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin and is accessing any account Account other than themselves") | |||
@@ -629,16 +629,16 @@ public class AccountsResource { | |||
@GET @Path("/{id}"+EP_MITM) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="Get status of mitmproxy", | |||
description="Get status of mitmproxy. Caller must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="returns true if mitmproxy is enabled, false otherwise", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="mitmproxy is enabled", value="true"), | |||
@ExampleObject(name="mitmproxy is disabled", value="false") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin"), | |||
@ApiResponse(responseCode=SC_INVALID, description="if mitmproxy not installed") | |||
} | |||
@@ -652,16 +652,16 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_MITM+EP_ENABLE) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="Enable mitmproxy", | |||
description="Enable mitmproxy. Caller must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="returns true if mitmproxy is enabled, false otherwise", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="mitmproxy is enabled", value="true"), | |||
@ExampleObject(name="mitmproxy is disabled", value="false") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin"), | |||
@ApiResponse(responseCode=SC_INVALID, description="if mitmproxy is not installed or an error occurred enabling it") | |||
} | |||
@@ -675,16 +675,16 @@ public class AccountsResource { | |||
@POST @Path("/{id}"+EP_MITM+EP_DISABLE) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="Disable mitmproxy", | |||
description="Disable mitmproxy. Caller must be admin.", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="returns true if mitmproxy is enabled, false otherwise", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="mitmproxy is enabled", value="true"), | |||
@ExampleObject(name="mitmproxy is disabled", value="false") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_FORBIDDEN, description="forbidden if caller is not admin"), | |||
@ApiResponse(responseCode=SC_INVALID, description="if mitmproxy is not installed or an error occurred disabling it") | |||
} | |||
@@ -754,11 +754,11 @@ public class AccountsResource { | |||
@GET @Path("/{id}"+EP_DEVICE_TYPES) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_UTILITY}, | |||
tags=API_TAG_UTILITY, | |||
summary="List all device types", | |||
description="List all device types", | |||
parameters={@Parameter(name="id", description="UUID or email of the Account")}, | |||
responses={@ApiResponse(responseCode=SC_OK, description="returns an array of Strings, each a BubbleDeviceType enum value")} | |||
parameters=@Parameter(name="id", description="UUID or email of the Account"), | |||
responses=@ApiResponse(responseCode=SC_OK, description="returns an array of Strings, each a BubbleDeviceType enum value") | |||
) | |||
public Response getDeviceTypes(@Context ContainerRequest ctx) { | |||
return ok(BubbleDeviceType.getSelectableTypes()); | |||
@@ -40,7 +40,6 @@ import io.swagger.v3.oas.annotations.Operation; | |||
import io.swagger.v3.oas.annotations.Parameter; | |||
import io.swagger.v3.oas.annotations.media.Content; | |||
import io.swagger.v3.oas.annotations.media.ExampleObject; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||
import io.swagger.v3.oas.annotations.security.SecurityRequirement; | |||
import lombok.Cleanup; | |||
@@ -133,17 +132,17 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_CONFIGS) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Read public system configuration", | |||
description="Read public system configuration", | |||
responses={@ApiResponse(responseCode=SC_OK, description="a Map<String, Object> of public system configuration settings")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="a Map<String, Object> of public system configuration settings") | |||
) | |||
public Response getPublicSystemConfigs(@Context ContainerRequest ctx) { | |||
return ok(configuration.getPublicSystemConfigs()); | |||
} | |||
@GET @Path(EP_READY) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@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", | |||
responses={ | |||
@@ -168,24 +167,24 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_ACTIVATE) | |||
@Operation(tags={API_TAG_ACTIVATION}, | |||
@Operation(tags=API_TAG_ACTIVATION, | |||
summary="Determine if the API has been activated", | |||
description="Determine if the API has been activated", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="returns true if API is activated, false otherwise", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="Bubble is activated", value="true"), | |||
@ExampleObject(name="Bubble has not been activated", value="false") | |||
})}) | |||
})) | |||
} | |||
) | |||
public Response isActivated(@Context ContainerRequest ctx) { return ok(accountDAO.activated()); } | |||
@GET @Path(EP_ACTIVATE+EP_CONFIGS) | |||
@Operation(tags={API_TAG_ACTIVATION}, | |||
@Operation(tags=API_TAG_ACTIVATION, | |||
summary="Get activation default configuration", | |||
description="Get activation default configuration", | |||
responses={@ApiResponse(responseCode=SC_OK, description="returns an array of CloudService[] representing the default CloudServices and their settings")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="returns an array of CloudService[] representing the default CloudServices and their settings") | |||
) | |||
public Response getActivationConfigs(@Context ContainerRequest ctx) { | |||
final Account caller = optionalUserPrincipal(ctx); | |||
@@ -195,7 +194,7 @@ public class AuthResource { | |||
@Transactional | |||
@PUT @Path(EP_ACTIVATE) | |||
@Operation(tags={API_TAG_ACTIVATION}, | |||
@Operation(tags=API_TAG_ACTIVATION, | |||
summary="Perform one-time activation", | |||
description="Perform one-time activation", | |||
responses={ | |||
@@ -261,10 +260,10 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_RESTORE+"/{restoreKey}") | |||
@Operation(tags={API_TAG_BACKUP_RESTORE}, | |||
@Operation(tags=API_TAG_BACKUP_RESTORE, | |||
summary="Restore a Bubble from a backup stored by sage.", | |||
description="Restore a Bubble from a backup stored by sage.", | |||
parameters={@Parameter(name="restoreKey", description="the restore key")}, | |||
parameters=@Parameter(name="restoreKey", description="the restore key"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the NotificationReceipt from a successful request to retrieve the backup"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred") | |||
@@ -294,10 +293,10 @@ public class AuthResource { | |||
@POST @Path(EP_RESTORE + EP_APPLY + "/{restoreKey}") | |||
@Consumes(MULTIPART_FORM_DATA) | |||
@Operation(tags={API_TAG_BACKUP_RESTORE}, | |||
@Operation(tags=API_TAG_BACKUP_RESTORE, | |||
summary="Restore a Bubble from a backup uploaded by user.", | |||
description="Restore a Bubble from a backup uploaded by user.", | |||
parameters={@Parameter(name="restoreKey", description="the restore key")}, | |||
parameters=@Parameter(name="restoreKey", description="the restore key"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="upon success a 200 HTTP status with an empty response is returned"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred") | |||
@@ -323,11 +322,11 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_REGISTER) | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Register a new Account, starts a new API session.", | |||
description="Register a new Account, starts a new API session.", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was registered, `token` property holds session token", content=@Content(mediaType=APPLICATION_JSON, schema=@Schema(ref="#/components/schema/Account"))), | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was registered, `token` property holds session token"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred") | |||
} | |||
) | |||
@@ -439,10 +438,10 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_LOGIN) | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Login an Account, starts a new API session.", | |||
description="Login an Account, starts a new API session.", | |||
parameters={@Parameter(name="k", description="for a new Bubble that was launched with the lock enabled, the unlock key is required for the first login")}, | |||
parameters=@Parameter(name="k", description="for a new Bubble that was launched with the lock enabled, the unlock key is required for the first login"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was logged in"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred") | |||
@@ -520,10 +519,10 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_APP_LOGIN+"/{session}") | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Login an Account using an existing session token, starts a new API session. If an existing session exists, it is invalidated", | |||
description="Login an Account using an existing session token, starts a new API session. If an existing session exists, it is invalidated", | |||
parameters={@Parameter(name="session", description="the session token to use for logging in")}, | |||
parameters=@Parameter(name="session", description="the session token to use for logging in"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="the Account object that was logged in"), | |||
@ApiResponse(responseCode=SC_INVALID, description="validation errors occurred") | |||
@@ -589,7 +588,7 @@ public class AuthResource { | |||
public TrustedAuthResource getTrustedAuthResource() { return configuration.subResource(TrustedAuthResource.class); } | |||
@POST @Path(EP_VERIFY_KEY) | |||
@Operation(tags={API_TAG_NODE}, | |||
@Operation(tags=API_TAG_NODE, | |||
summary="Called between Bubbles to verify RSA keys", | |||
description="Called between Bubbles to verify RSA keys", | |||
responses={ | |||
@@ -651,7 +650,7 @@ public class AuthResource { | |||
@POST @Path(EP_REKEY) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_NODE}, | |||
tags=API_TAG_NODE, | |||
summary="Re-key a node. Must be admin. Creates a new NodeKey that, being newest, will be the one the node starts using", | |||
description="Re-key a node. Must be admin. Creates a new NodeKey that, being newest, will be the one the node starts using", | |||
responses={ | |||
@@ -697,7 +696,7 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_FORGOT_PASSWORD) | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Send a reset password message", | |||
description="Send a reset password message", | |||
responses={ | |||
@@ -728,16 +727,16 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_APPROVE+"/{token}") | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Approve a request", | |||
description="Approve a request. The token comes from an email or SMS message sent to the user.", | |||
parameters={@Parameter(name="token", description="the confirmation token")}, | |||
parameters=@Parameter(name="token", description="the confirmation token"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="if no login requested, returns an empty response", value=""), | |||
@ExampleObject(name="if login requested, returns an Account object with either a valid session token ('token' property) or additional auth factors required (check 'multifactorAuth' property)") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the token might be invalid") | |||
} | |||
) | |||
@@ -778,15 +777,15 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_AUTHENTICATOR) | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Approve a TOTP request", | |||
description="Approve a TOTP request. The token comes the end user's authenticator app.", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="if no login requested, returns an empty response", value=""), | |||
@ExampleObject(name="if login requested, returns an Account object with either a valid session token ('token' property) or additional auth factors required (check 'multifactorAuth' property)") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the token might be invalid") | |||
} | |||
) | |||
@@ -843,14 +842,14 @@ public class AuthResource { | |||
@DELETE @Path(EP_AUTHENTICATOR) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_AUTH}, | |||
tags=API_TAG_AUTH, | |||
summary="Flush authenticator tokens", | |||
description="Flush authenticator tokens. The next operation that requires TOTP auth will require the user to re-authenticate.", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="returns an empty JSON object", value="{}") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the token might be invalid") | |||
} | |||
) | |||
@@ -862,15 +861,15 @@ public class AuthResource { | |||
} | |||
@POST @Path(EP_DENY+"/{token}") | |||
@Operation(tags={API_TAG_AUTH}, | |||
@Operation(tags=API_TAG_AUTH, | |||
summary="Deny a request", | |||
description="Deny a request. The token comes from an email or SMS message sent to the user.", | |||
parameters={@Parameter(name="token", description="the confirmation token")}, | |||
parameters=@Parameter(name="token", description="the confirmation token"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={ | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="returns the denial AccountMessage") | |||
})}), | |||
})), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the token might be invalid") | |||
} | |||
) | |||
@@ -887,14 +886,14 @@ public class AuthResource { | |||
@GET @Path(EP_CA_CERT) | |||
@Produces(CONTENT_TYPE_ANY) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get the CA Certificate for this Bubble", | |||
description="Get the CA Certificate for this Bubble. Response body is the certificate itself, in a format determined by deviceType or type", | |||
parameters={ | |||
@Parameter(name="deviceType", description="the device type"), | |||
@Parameter(name="type", description="the certificate type") | |||
}, | |||
responses={@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success, response body is certificate")} | |||
responses=@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success, response body is certificate") | |||
) | |||
public Response getCaCert(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -925,12 +924,10 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_KEY) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get the Node Key for this Bubble", | |||
description="Get the Node Key for this Bubble", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success") | |||
) | |||
public Response getNodeKey(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
@@ -952,10 +949,10 @@ public class AuthResource { | |||
@GET @Path(EP_LOGOUT) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_AUTH}, | |||
tags=API_TAG_AUTH, | |||
summary="Logout", | |||
description="Logout of the current session, or logout of all sessions everywhere if the `all` parameter is true.", | |||
parameters={@Parameter(name="all", description="logout of all sessions everywhere")}, | |||
parameters=@Parameter(name="all", description="logout of all sessions everywhere"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success"), | |||
@ApiResponse(responseCode=SC_INVALID, description="If there is no current session to log out of") | |||
@@ -975,10 +972,10 @@ public class AuthResource { | |||
@POST @Path(EP_LOGOUT+"/{id}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_AUTH}, | |||
tags=API_TAG_AUTH, | |||
summary="Logout a user everywhere", | |||
description="Logout of the current session, or logout of all sessions everywhere if the `all` parameter is true.", | |||
parameters={@Parameter(name="id", description="UUID or email of user to logout")}, | |||
parameters=@Parameter(name="id", description="UUID or email of user to logout"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success"), | |||
@ApiResponse(responseCode=SC_INVALID, description="If there is no current session to log out of") | |||
@@ -1000,25 +997,21 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_TIME) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get current system time", | |||
description="Get current system time. Returns current time as epoch time in milliseconds", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="Returns current time as epoch time in milliseconds", | |||
content={@Content(mediaType=APPLICATION_JSON, examples={@ExampleObject(name="time in milliseconds", value="1606858589683")})}) | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="Returns current time as epoch time in milliseconds", | |||
content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="time in milliseconds", value="1606858589683"))) | |||
) | |||
public Response serverTime() { return ok(now()); } | |||
@Autowired private GeoService geoService; | |||
@GET @Path(EP_SUPPORT) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get support information", | |||
description="Get support information for the user's current locale, if available. Use the default locale otherwise.", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="SupportInfo object") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="SupportInfo object") | |||
) | |||
public Response getSupportInfo (@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
@@ -1027,13 +1020,11 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_SUPPORT+"/{locale}") | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get support information", | |||
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") | |||
} | |||
parameters=@Parameter(name="locale", description="locale to find support for"), | |||
responses=@ApiResponse(responseCode=SC_OK, description="SupportInfo object") | |||
) | |||
public Response getSupportInfo (@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -1042,12 +1033,10 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_APP_LINKS) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get links to native applications", | |||
description="Get links to native applications for the current user's locale, if available. Use the default locale otherwise.", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="AppLinks object") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="AppLinks object") | |||
) | |||
public Response getAppLinks (@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
@@ -1056,13 +1045,11 @@ public class AuthResource { | |||
} | |||
@GET @Path(EP_APP_LINKS+"/{locale}") | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get links to native applications", | |||
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") | |||
} | |||
parameters=@Parameter(name="locale", description="locale to find app links for"), | |||
responses=@ApiResponse(responseCode=SC_OK, description="AppLinks object") | |||
) | |||
public Response getAppLinks (@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@@ -1072,12 +1059,12 @@ public class AuthResource { | |||
@GET @Path(EP_PATCH+"/{token}") | |||
@Produces(APPLICATION_OCTET_STREAM) | |||
@Operation(tags={API_TAG_NODE_MANAGER}, | |||
@Operation(tags=API_TAG_NODE_MANAGER, | |||
summary="Find a node-manager patch file", | |||
description="Find a node-manager patch file. The file must previously have been registered, yielding a token", | |||
parameters={@Parameter(name="token", description="token of the patch file to retrieve")}, | |||
parameters=@Parameter(name="token", description="token of the patch file to retrieve"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="raw file data", content={@Content(mediaType=APPLICATION_OCTET_STREAM)}), | |||
@ApiResponse(responseCode=SC_OK, description="raw file data", content=@Content(mediaType=APPLICATION_OCTET_STREAM)), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="token not valid") | |||
} | |||
) | |||
@@ -1092,7 +1079,7 @@ public class AuthResource { | |||
@GET @Path(EP_UPGRADE+"/{node}/{key}") | |||
@Produces(APPLICATION_OCTET_STREAM) | |||
@Operation(tags={API_TAG_NODE}, | |||
@Operation(tags=API_TAG_NODE, | |||
summary="Return bubble jar", | |||
description="Return bubble jar file for upgrading other nodes to our version.", | |||
parameters={ | |||
@@ -1100,7 +1087,7 @@ public class AuthResource { | |||
@Parameter(name="key", description="UUID of the calling node's BubbleNodeKey") | |||
}, | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="raw jar file data", content={@Content(mediaType=APPLICATION_OCTET_STREAM)}), | |||
@ApiResponse(responseCode=SC_OK, description="raw jar file data", content=@Content(mediaType=APPLICATION_OCTET_STREAM)), | |||
@ApiResponse(responseCode=SC_UNAUTHORIZED, description="calling node is not authorized"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="token not valid") | |||
} | |||
@@ -35,6 +35,7 @@ import bubble.service.cloud.NodeLaunchMonitor; | |||
import bubble.service.upgrade.BubbleJarUpgradeService; | |||
import com.fasterxml.jackson.databind.JsonNode; | |||
import io.swagger.v3.oas.annotations.Operation; | |||
import io.swagger.v3.oas.annotations.Parameter; | |||
import io.swagger.v3.oas.annotations.media.Content; | |||
import io.swagger.v3.oas.annotations.media.ExampleObject; | |||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||
@@ -78,8 +79,7 @@ import static bubble.resources.account.AuthResource.forgotPasswordMessage; | |||
import static java.util.concurrent.TimeUnit.MINUTES; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | |||
import static org.cobbzilla.util.http.HttpContentTypes.*; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_OK; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.SC_INVALID; | |||
import static org.cobbzilla.util.http.HttpStatusCodes.*; | |||
import static org.cobbzilla.util.json.JsonUtil.json; | |||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | |||
import static org.cobbzilla.wizard.server.RestServerBase.reportError; | |||
@@ -102,12 +102,10 @@ public class MeResource { | |||
@GET | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Get account record for current session", | |||
description="Get account record for current session", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="Account object") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="Account object") | |||
) | |||
public Response me(@Context ContainerRequest ctx) { | |||
try { | |||
@@ -127,12 +125,10 @@ public class MeResource { | |||
@GET @Path(EP_LOCALE) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Get the account locale", | |||
description="Get the account locale", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="Locale string", content=@Content(mediaType=APPLICATION_JSON, examples={@ExampleObject(name="default locale", value="en_US")})) | |||
} | |||
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) { | |||
final Account account = userPrincipal(ctx); | |||
@@ -141,12 +137,10 @@ public class MeResource { | |||
@POST @Path(EP_LOCALE+"/{locale}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Set the account locale", | |||
description="Set the account locale", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="updated Account object") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="updated Account object") | |||
) | |||
public Response setLocale(@Context ContainerRequest ctx, | |||
@PathParam("locale") String locale) { | |||
@@ -177,18 +171,16 @@ public class MeResource { | |||
} | |||
@GET @Path(EP_ERROR_API) | |||
@Operation(tags={API_TAG_UTILITY}, | |||
@Operation(tags=API_TAG_UTILITY, | |||
summary="Get error API information", | |||
description="Get error API information", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="a Map of API information") | |||
} | |||
responses=@ApiResponse(responseCode=SC_OK, description="a Map of API information") | |||
) | |||
public Response errorApi(@Context Request req) { return ok(getErrorApi()); } | |||
@POST @Path(EP_CHANGE_PASSWORD) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags={API_TAG_ACCOUNT}, | |||
tags=API_TAG_ACCOUNT, | |||
summary="Request account password change", | |||
description="Request account password change. A message will be sent to the user with a token to approve the change and set a new password. If the password can be changed directly, this returns the updated Account object. If approvals are required for a password change, an Account object will be returned and the `multifactorAuth` property will indicate what auth methods are required to approve the change.", | |||
responses={ | |||
@@ -248,7 +240,20 @@ public class MeResource { | |||
@Autowired private StandardAccountMessageService messageService; | |||
@POST @Path(EP_APPROVE+"/{token}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_AUTH, | |||
summary="Approve a request", | |||
description="Approve a request. The token comes from an email or SMS message sent to the user.", | |||
parameters=@Parameter(name="token", description="the confirmation token"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success", | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="if no login requested, returns an empty response", value=""), | |||
@ExampleObject(name="if login requested, returns an Account object with either a valid session token ('token' property) or additional auth factors required (check 'multifactorAuth' property)") | |||
})), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the token might be invalid") | |||
} | |||
) | |||
public Response approve(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@PathParam("token") String token) { | |||
@@ -265,7 +270,20 @@ public class MeResource { | |||
} | |||
@POST @Path(EP_DENY+"/{token}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_AUTH, | |||
summary="Deny a request", | |||
description="Deny a request. The token comes from an email or SMS message sent to the user.", | |||
parameters=@Parameter(name="token", description="the confirmation token"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success", | |||
content=@Content(mediaType=APPLICATION_JSON, examples={ | |||
@ExampleObject(name="returns the denial AccountMessage") | |||
})), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the token might be invalid"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="the token might be invalid") | |||
} | |||
) | |||
public Response deny(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@PathParam("token") String token) { | |||
@@ -276,7 +294,15 @@ public class MeResource { | |||
} | |||
@POST @Path(EP_DOWNLOAD) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_ACCOUNT, | |||
summary="Request account data download", | |||
description="Request account data download. This begins the process of collecting the account data.", | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="HTTP status 200 indicates success"), | |||
@ApiResponse(responseCode=SC_INVALID, description="a validation error occurred, for example the account has no verified contacts") | |||
} | |||
) | |||
public Response requestDownloadAccountData(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
final Account caller = userPrincipal(ctx); | |||
@@ -290,7 +316,16 @@ public class MeResource { | |||
} | |||
@POST @Path(EP_DOWNLOAD+"/{uuid}") | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_ACCOUNT, | |||
summary="Download account data", | |||
description="Download account data.", | |||
parameters=@Parameter(name="uuid", description="the uuid of the download to retrieve"), | |||
responses={ | |||
@ApiResponse(responseCode=SC_OK, description="Account data as JSON"), | |||
@ApiResponse(responseCode=SC_NOT_FOUND, description="uuid was invalid") | |||
} | |||
) | |||
public Response downloadAccountData(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@PathParam("uuid") String uuid) { | |||
@@ -301,7 +336,12 @@ public class MeResource { | |||
} | |||
@POST @Path(EP_SCRIPT) @Produces(TEXT_PLAIN) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_UTILITY, | |||
summary="Run an API script", | |||
description="Run an API script", | |||
responses=@ApiResponse(responseCode=SC_OK, description="Script output") | |||
) | |||
public Response runScript(@Context ContainerRequest ctx, | |||
JsonNode script) { | |||
final Account caller = userPrincipal(ctx); | |||
@@ -309,6 +349,8 @@ public class MeResource { | |||
final StringWriter writer = new StringWriter(); | |||
final ApiRunnerListener listener = new ApiRunnerListenerStreamLogger("runScript", writer); | |||
@Cleanup final ApiClientBase api = configuration.newApiClient(); | |||
api.setToken(caller.getToken()); | |||
final ApiRunner runner = new ApiRunner(api, listener); | |||
try { | |||
if (script.isArray()) { | |||
@@ -446,7 +488,12 @@ public class MeResource { | |||
@Autowired private NodeLaunchMonitor launchMonitor; | |||
@GET @Path(EP_STATUS) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_ACCOUNT, | |||
summary="List all launch statuses for an account", | |||
description="List all launch statuses for an account. Caller must be the same account, or must be admin.", | |||
responses=@ApiResponse(responseCode=SC_OK, description="a List<NodeProgressMeterTick> representing the status of active launch operations") | |||
) | |||
public Response listLaunchStatuses(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
final Account caller = userPrincipal(ctx); | |||
@@ -471,7 +518,16 @@ public class MeResource { | |||
@POST @Path(EP_MODEL) | |||
@Consumes(MULTIPART_FORM_DATA) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_UTILITY, | |||
summary="Load model objects", | |||
description="Load model objects", | |||
parameters={ | |||
@Parameter(name="file", description="model JSON"), | |||
@Parameter(name="name", description="name of model") | |||
}, | |||
responses=@ApiResponse(responseCode=SC_OK, description="the model that was loaded") | |||
) | |||
public Response uploadModel(@Context Request req, | |||
@Context ContainerRequest ctx, | |||
@FormDataParam("file") InputStream in, | |||
@@ -497,7 +553,12 @@ public class MeResource { | |||
private static final long UPGRADE_CHECK_INTERVAL = MINUTES.toMillis(5); | |||
@GET @Path(EP_UPGRADE) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY)) | |||
@Operation(security=@SecurityRequirement(name=SEC_API_KEY), | |||
tags=API_TAG_UTILITY, | |||
summary="Check for upgrade", | |||
description="Check for upgrade. Must be admin. The check runs in the background, this returns an empty JSON object", | |||
responses=@ApiResponse(responseCode=SC_OK, description="the upgrade check has been started", content=@Content(mediaType=APPLICATION_JSON, examples=@ExampleObject(name="empty JSON object", value="{}"))) | |||
) | |||
public Response checkForUpgrade(@Context Request req, | |||
@Context ContainerRequest ctx) { | |||
final Account caller = userPrincipal(ctx); | |||
@@ -18,6 +18,7 @@ openApi: | |||
additionalPackages: | |||
- org.cobbzilla.wizard.model.search | |||
- org.cobbzilla.wizard.model.support | |||
- bubble.cloud | |||
defaultLocale: {{#exists BUBBLE_DEFAULT_LOCALE}}{{BUBBLE_DEFAULT_LOCALE}}{{else}}en_US{{/exists}} | |||
testMode: {{#exists BUBBLE_TEST_MODE}}{{BUBBLE_TEST_MODE}}{{else}}false{{/exists}} | |||
@@ -1 +1 @@ | |||
Subproject commit 51119dc923d483f8b97fb0de3b36e3ff893e2ee9 | |||
Subproject commit 2c3bfe646107b1b0ff9a3c4b001f051e4bd81fa0 |
@@ -1 +1 @@ | |||
Subproject commit 126e4b4da345a14006998703147f4744c535a0df | |||
Subproject commit f12add50c534143a443b09bf275211ee603563b4 |