| /* |
| * 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(); |
| } |
| } |