alluxio.security.authorization.ModeParser.java Source code

Java tutorial

Introduction

Here is the source code for alluxio.security.authorization.ModeParser.java

Source

/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.security.authorization;

import alluxio.exception.ExceptionMessage;
import alluxio.security.authorization.Mode.Bits;

import org.apache.commons.lang3.StringUtils;

import javax.annotation.concurrent.ThreadSafe;

/**
 * Parser for {@code Mode} instances.
 * @author rvesse
 *
 */
@ThreadSafe
public final class ModeParser {

    private static final char[] VALID_TARGETS = { 'u', 'g', 'o', 'a' };
    private static final char[] VALID_PERMISSIONS = { 'r', 'w', 'x' };

    /**
     * Creates a new parser.
     */
    public ModeParser() {
    }

    /**
     * Parses the given value as a mode.
     * @param value Value
     * @return Mode
     */
    public Mode parse(String value) {
        if (StringUtils.isBlank(value)) {
            throw new IllegalArgumentException(ExceptionMessage.INVALID_MODE.getMessage(value));
        }

        try {
            return parseNumeric(value);
        } catch (NumberFormatException e) {
            // Treat as symbolic
            return parseSymbolic(value);
        }
    }

    private Mode parseNumeric(String value) {
        short s = Short.parseShort(value, 8);
        return new Mode(s);
    }

    private Mode parseSymbolic(String value) {
        Mode.Bits ownerBits = Bits.NONE;
        Mode.Bits groupBits = Bits.NONE;
        Mode.Bits otherBits = Bits.NONE;

        String[] specs = value.contains(",") ? value.split(",") : new String[] { value };
        for (String spec : specs) {
            String[] specParts = spec.split("=");

            // Validate that the spec is usable
            // Must have targets=perm i.e. 2 parts
            // Targets must be in u, g, o and a
            // Permissions must be in r, w and x
            if (specParts.length != 2) {
                throw new IllegalArgumentException(ExceptionMessage.INVALID_MODE_SEGMENT.getMessage(value, spec));
            }
            if (!StringUtils.containsOnly(specParts[0], VALID_TARGETS)) {
                throw new IllegalArgumentException(
                        ExceptionMessage.INVALID_MODE_TARGETS.getMessage(value, spec, specParts[0]));
            }
            if (!StringUtils.containsOnly(specParts[1], VALID_PERMISSIONS)) {
                throw new IllegalArgumentException(
                        ExceptionMessage.INVALID_MODE_PERMISSIONS.getMessage(value, spec, specParts[1]));
            }

            // Build the permissions being specified
            Mode.Bits specBits = Bits.NONE;
            for (char permChar : specParts[1].toCharArray()) {
                switch (permChar) {
                case 'r':
                    specBits = specBits.or(Bits.READ);
                    break;
                case 'w':
                    specBits = specBits.or(Bits.WRITE);
                    break;
                case 'x':
                    specBits = specBits.or(Bits.EXECUTE);
                    break;
                default:
                    // Should never get here as already checked for invalid targets
                }
            }

            // Apply them to the targets
            for (char targetChar : specParts[0].toCharArray()) {
                switch (targetChar) {
                case 'u':
                    ownerBits = ownerBits.or(specBits);
                    break;
                case 'g':
                    groupBits = groupBits.or(specBits);
                    break;
                case 'o':
                    otherBits = otherBits.or(specBits);
                    break;
                case 'a':
                    ownerBits = ownerBits.or(specBits);
                    groupBits = groupBits.or(specBits);
                    otherBits = otherBits.or(specBits);
                    break;
                default:
                    // Should never get here as already checked for invalid targets
                }
            }
        }

        // Return the resulting mode
        return new Mode(ownerBits, groupBits, otherBits);
    }
}