Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change API to delete based on host #1785

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 79 additions & 43 deletions apps/dashboard/src/main/java/com/akto/action/InternalAction.java
Original file line number Diff line number Diff line change
@@ -1,83 +1,111 @@
package com.akto.action;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.akto.dao.ApiCollectionsDao;
import com.akto.dao.SingleTypeInfoDao;
import com.akto.dao.context.Context;
import com.akto.dto.ApiCollection;
import com.akto.dto.ApiInfo.ApiInfoKey;
import com.akto.dto.User;
import com.akto.dto.traffic.Key;
import com.akto.dto.type.SingleTypeInfo;
import com.akto.log.LoggerMaker;
import com.akto.log.LoggerMaker.LogDb;
import com.akto.usage.UsageMetricCalculator;
import com.mongodb.client.model.Filters;

public class InternalAction extends UserAction {
private static final LoggerMaker loggerMaker = new LoggerMaker(InternalAction.class, LogDb.DASHBOARD);

String headerKey;
boolean actuallyDelete;
int count;
int timestamp;

public String deleteApisBasedOnHeader() {

if (headerKey == null || headerKey.isEmpty()) {
addActionError("Invalid header key");
return ERROR.toUpperCase();
}
public String deleteApisWithoutHost() {

User user = getSUser();
if (user.getLogin() != null && !user.getLogin().contains("@akto")) {
addActionError("Illegal operation");
return ERROR.toUpperCase();
}

int time = Context.now();
Bson filter = Filters.and(Filters.eq(SingleTypeInfo._PARAM, headerKey),
UsageMetricCalculator.excludeDemosAndDeactivated(SingleTypeInfo._API_COLLECTION_ID));
loggerMaker.infoAndAddToDb("Executing deleteApisBasedOnHeader find query");
List<ApiInfoKey> apiList = SingleTypeInfoDao.instance.fetchEndpointsInCollection(filter);

int delta = Context.now() - time;
loggerMaker.infoAndAddToDb("Finished deleteApisBasedOnHeader find query " + delta);
List<ApiCollection> apiCollections = ApiCollectionsDao.fetchAllHosts();

if (apiList != null && !apiList.isEmpty()) {
Set<Key> keys = new HashSet<>();
int time = Context.nowInMillis();
int delta = Context.nowInMillis();
Set<Integer> demosAndDeactivated = UsageMetricCalculator.getDemosAndDeactivated();
for (ApiCollection apiCollection : apiCollections) {

List<Key> keys = new ArrayList<>();
for (ApiInfoKey apiInfoKey : apiList) {
loggerMaker.infoAndAddToDb("deleteApisBasedOnHeader " + apiInfoKey.toString());
keys.add(new Key(apiInfoKey.getApiCollectionId(), apiInfoKey.getUrl(), apiInfoKey.getMethod(), -1, 0,
0));

int apiCollectionId = apiCollection.getId();
if (demosAndDeactivated.contains(apiCollectionId)) {
loggerMaker.infoAndAddToDb("Skipping deleteApisBasedOnHeader for apiCollectionId " + apiCollectionId);
continue;
}

count = apiList.size();
if (actuallyDelete) {
try {
time = Context.now();
loggerMaker.infoAndAddToDb("deleteApisBasedOnHeader deleting APIs");
com.akto.utils.Utils.deleteApis(keys);
delta = Context.now() - time;
loggerMaker.infoAndAddToDb("deleteApisBasedOnHeader deleted APIs " + delta);
} catch (Exception e) {
e.printStackTrace();
addActionError("Error deleting APIs");
return ERROR.toUpperCase();

List<Bson> pipeline = Arrays.asList(new Document("$match",
new Document("$and", Arrays.asList(new Document("$or", Arrays.asList(
new Document("lastSeen", new Document("$gt", timestamp)),
new Document("timestamp", new Document("$gt", timestamp)))),
new Document("apiCollectionId", apiCollectionId)))),
new Document("$group",
new Document("_id",
new Document("apiCollectionId", "$apiCollectionId")
.append("url", "$url")
.append("method", "$method"))
.append("hasHostParam",
new Document("$max",
new Document("$cond",
Arrays.asList(new Document("$eq",
Arrays.asList("$param", "host")), 1L, 0L))))
.append("documents",
new Document("$push", "$$ROOT"))),
new Document("$match",
new Document("hasHostParam",
new Document("$eq", 0L))),
new Document("$project",
new Document("_id", 1L)));

time = Context.nowInMillis();
loggerMaker.infoAndAddToDb("Executing deleteApisBasedOnHeader find query " + apiCollectionId);
List<ApiInfoKey> apiList = SingleTypeInfoDao.instance.processPipelineForEndpoint(pipeline);
delta = Context.nowInMillis() - time;
loggerMaker.infoAndAddToDb("Finished deleteApisBasedOnHeader find query " + delta + " " + apiCollectionId);
if (apiList != null && !apiList.isEmpty()) {
for (ApiInfoKey apiInfoKey : apiList) {
loggerMaker.infoAndAddToDb("deleteApisBasedOnHeader " + apiInfoKey.toString());
keys.add(
new Key(apiInfoKey.getApiCollectionId(), apiInfoKey.getUrl(), apiInfoKey.getMethod(), -1, 0,
0));
}
}
}
return SUCCESS.toUpperCase();
}

public String getHeaderKey() {
return headerKey;
}
count = keys.size();
if (keys != null && !keys.isEmpty() && actuallyDelete) {
try {
time = Context.nowInMillis();
loggerMaker.infoAndAddToDb("deleteApisBasedOnHeader deleting APIs");
List<Key> keyList = new ArrayList<>();
keyList.addAll(keys);
com.akto.utils.Utils.deleteApis(keyList);
delta = Context.nowInMillis() - time;
loggerMaker.infoAndAddToDb("deleteApisBasedOnHeader deleted APIs " + delta);
} catch (Exception e) {
e.printStackTrace();
addActionError("Error deleting APIs");
return ERROR.toUpperCase();
}
}

public void setHeaderKey(String headerKey) {
this.headerKey = headerKey;
return SUCCESS.toUpperCase();
}

public boolean getActuallyDelete() {
Expand All @@ -95,4 +123,12 @@ public int getCount() {
public void setCount(int count) {
this.count = count;
}

public int getTimestamp() {
return timestamp;
}

public void setTimestamp(int timestamp) {
this.timestamp = timestamp;
}
}
2 changes: 1 addition & 1 deletion apps/dashboard/src/main/resources/struts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2060,7 +2060,7 @@
</result>
</action>

<action name="api/deleteApisBasedOnHeader" class="com.akto.action.InternalAction" method="deleteApisBasedOnHeader">
<action name="api/deleteApisWithoutHost" class="com.akto.action.InternalAction" method="deleteApisWithoutHost">
<interceptor-ref name="json"/>
<interceptor-ref name="defaultStack" />
<result name="FORBIDDEN" type="json">
Expand Down
8 changes: 1 addition & 7 deletions libs/dao/src/main/java/com/akto/dao/SingleTypeInfoDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,6 @@ public List<ApiInfo.ApiInfoKey> fetchEndpointsInCollection(int apiCollectionId)
return processPipelineForEndpoint(pipeline);
}

public List<ApiInfo.ApiInfoKey> fetchEndpointsInCollection(Bson filter) {
List<Bson> pipeline = getPipelineForEndpoints(filter);
pipeline.add(Aggregates.limit(SingleTypeInfoDao.LARGE_LIMIT));
return processPipelineForEndpoint(pipeline);
}

public List<ApiInfo.ApiInfoKey> fetchEndpointsInCollection(Method method) {
Bson filter = null;
if (method == null) {
Expand Down Expand Up @@ -412,7 +406,7 @@ private List<Bson> getPipelineForEndpoints(Bson matchCriteria) {
return pipeline;
}

private List<ApiInfoKey> processPipelineForEndpoint(List<Bson> pipeline){
public List<ApiInfoKey> processPipelineForEndpoint(List<Bson> pipeline){
MongoCursor<BasicDBObject> endpointsCursor = instance.getMCollection().aggregate(pipeline, BasicDBObject.class).cursor();

List<ApiInfo.ApiInfoKey> endpoints = new ArrayList<>();
Expand Down
Loading