001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.security.visibility;
019
020import java.util.ArrayList;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Set;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.security.User;
026import org.apache.yetus.audience.InterfaceAudience;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030/**
031 * This is an implementation for ScanLabelGenerator. It will extract labels from passed in
032 * authorizations and cross check against the set of predefined authorization labels for given user.
033 * The labels for which the user is not authorized will be dropped.
034 */
035@InterfaceAudience.Private
036public class DefinedSetFilterScanLabelGenerator implements ScanLabelGenerator {
037  private static final Logger LOG =
038    LoggerFactory.getLogger(DefinedSetFilterScanLabelGenerator.class);
039
040  private Configuration conf;
041
042  private VisibilityLabelsCache labelsCache;
043
044  public DefinedSetFilterScanLabelGenerator() {
045    this.labelsCache = VisibilityLabelsCache.get();
046  }
047
048  @Override
049  public void setConf(Configuration conf) {
050    this.conf = conf;
051  }
052
053  @Override
054  public Configuration getConf() {
055    return this.conf;
056  }
057
058  @Override
059  public List<String> getLabels(User user, Authorizations authorizations) {
060    if (authorizations != null) {
061      List<String> labels = authorizations.getLabels();
062      String userName = user.getShortName();
063      Set<String> auths = new HashSet<>();
064      auths.addAll(this.labelsCache.getUserAuths(userName));
065      auths.addAll(this.labelsCache.getGroupAuths(user.getGroupNames()));
066      return dropLabelsNotInUserAuths(labels, new ArrayList<>(auths), userName);
067    }
068    return null;
069  }
070
071  private List<String> dropLabelsNotInUserAuths(List<String> labels, List<String> auths,
072    String userName) {
073    List<String> droppedLabels = new ArrayList<>();
074    List<String> passedLabels = new ArrayList<>(labels.size());
075    for (String label : labels) {
076      if (auths.contains(label)) {
077        passedLabels.add(label);
078      } else {
079        droppedLabels.add(label);
080      }
081    }
082    if (!droppedLabels.isEmpty()) {
083      StringBuilder sb = new StringBuilder();
084      sb.append("Dropping invalid authorizations requested by user ");
085      sb.append(userName);
086      sb.append(": [ ");
087      for (String label : droppedLabels) {
088        sb.append(label);
089        sb.append(' ');
090      }
091      sb.append(']');
092      LOG.warn(sb.toString());
093    }
094    return passedLabels;
095  }
096}