blob: 860da55750185f43973ddc59293d472bfaf9e720 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.apache.hugegraph.api.profile;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.hugegraph.api.API;
import org.apache.hugegraph.api.filter.StatusFilter;
import org.apache.hugegraph.auth.AuthManager;
import org.apache.hugegraph.core.GraphManager;
import org.apache.hugegraph.util.E;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;
import com.codahale.metrics.annotation.Timed;
import com.google.common.collect.ImmutableMap;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Singleton;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;
@Path("whiteiplist")
@Singleton
@Tag(name = "WhiteIpListAPI")
public class WhiteIpListAPI extends API {
private static final Logger LOG = Log.logger(WhiteIpListAPI.class);
@GET
@Timed
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed("admin")
@Operation(summary = "list white ips")
public Map<String, Object> list(@Context GraphManager manager) {
LOG.debug("List white ips");
AuthManager authManager = manager.authManager();
Set<String> whiteIpList = authManager.listWhiteIPs();
return ImmutableMap.of("whiteIpList", whiteIpList);
}
@POST
@Timed
@StatusFilter.Status(StatusFilter.Status.ACCEPTED)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed("admin")
@Operation(summary = "update white ip list")
public Map<String, Object> updateWhiteIPs(@Context GraphManager manager, Map<String, Object> actionMap) {
E.checkArgument(actionMap != null,
"Missing argument: actionMap");
Set<String> whiteIpList = manager.authManager().listWhiteIPs();
Object ipListRaw = actionMap.get("ips");
E.checkArgument(ipListRaw instanceof List,
"Invalid ips type '%s', must be list", ipListRaw.getClass());
List<String> ipList = (List<String>) ipListRaw;
Object actionRaw = actionMap.get("action");
E.checkArgument(actionRaw != null,
"Missing argument: action");
E.checkArgument(actionRaw instanceof String,
"Invalid action type '%s', must be string",
actionRaw.getClass());
String action = (String) actionRaw;
E.checkArgument(StringUtils.isNotEmpty(action),
"Missing argument: action");
Set<String> existedIPs = new HashSet<>();
Set<String> loadedIPs = new HashSet<>();
Set<String> illegalIPs = new HashSet<>();
Map<String, Object> result = new HashMap<>();
for (String ip : ipList) {
if (whiteIpList.contains(ip)) {
existedIPs.add(ip);
continue;
}
if ("load".equals(action)) {
boolean rightIp = checkIp(ip) ? loadedIPs.add(ip) : illegalIPs.add(ip);
}
}
switch (action) {
case "load":
LOG.debug("Load to white ip list");
result.put("existed_ips", existedIPs);
result.put("added_ips", loadedIPs);
if (!illegalIPs.isEmpty()) {
result.put("illegal_ips", illegalIPs);
}
whiteIpList.addAll(loadedIPs);
break;
case "remove":
LOG.debug("Remove from white ip list");
result.put("removed_ips", existedIPs);
result.put("non_existed_ips", loadedIPs);
whiteIpList.removeAll(existedIPs);
break;
default:
throw new AssertionError(String.format("Invalid action '%s', " +
"supported action is " +
"'load' or 'remove'",
action));
}
manager.authManager().setWhiteIPs(whiteIpList);
return result;
}
@PUT
@Timed
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed("admin")
@Operation(summary = "enable/disable the white ip list")
public Map<String, Object> updateStatus(@Context GraphManager manager, @QueryParam("status") String status) {
LOG.debug("Enable or disable white ip list");
E.checkArgument("true".equals(status) ||
"false".equals(status),
"Invalid status, valid status is 'true' or 'false'");
boolean open = Boolean.parseBoolean(status);
manager.authManager().enabledWhiteIpList(open);
Map<String, Object> map = new HashMap<>();
map.put("WhiteIpListOpen", open);
return map;
}
private boolean checkIp(String ipStr) {
String ip = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
+ "(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
Pattern pattern = Pattern.compile(ip);
Matcher matcher = pattern.matcher(ipStr);
return matcher.matches();
}
}