PrivEntry.java
// 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.doris.mysql.privilege;
import org.apache.doris.analysis.UserIdentity;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.CaseSensibility;
import org.apache.doris.common.PatternMatcher;
import org.apache.doris.common.PatternMatcherException;
import org.apache.doris.common.io.Text;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.NotImplementedException;
import java.io.DataInput;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public abstract class PrivEntry implements Comparable<PrivEntry> {
@Deprecated
protected static final String ANY_HOST = "%";
@Deprecated
protected static final String ANY_USER = "%";
protected PrivBitSet privSet;
// host is not case sensitive
@Deprecated
protected PatternMatcher hostPattern;
@Deprecated
protected String origHost;
@Deprecated
protected boolean isAnyHost = false;
// user name is case sensitive
@Deprecated
protected PatternMatcher userPattern;
@Deprecated
protected String origUser;
@Deprecated
protected boolean isAnyUser = false;
// true if this entry is set by domain resolver
@Deprecated
protected boolean isSetByDomainResolver = false;
// true if origHost is a domain name.
// For global priv entry, if isDomain is true, it should only be used for priv checking, not password checking
@Deprecated
protected boolean isDomain = false;
// isClassNameWrote to guarantee the class name can only be written once when persisting.
// see PrivEntry.read() for more details.
@Deprecated
protected boolean isClassNameWrote = false;
@Deprecated
protected UserIdentity userIdentity;
protected PrivEntry() {
}
protected PrivEntry(PrivBitSet privSet) {
this.privSet = privSet;
}
public PrivBitSet getPrivSet() {
return privSet;
}
public void setPrivSet(PrivBitSet privSet) {
this.privSet = privSet;
}
@Deprecated
public void setSetByDomainResolver(boolean isSetByDomainResolver) {
this.isSetByDomainResolver = isSetByDomainResolver;
}
public abstract boolean keyMatch(PrivEntry other);
@Deprecated
protected PrivEntry(PatternMatcher hostPattern, String origHost, PatternMatcher userPattern, String origUser,
boolean isDomain, PrivBitSet privSet) {
this.hostPattern = hostPattern;
this.origHost = origHost;
if (origHost.equals(ANY_HOST)) {
isAnyHost = true;
}
this.userPattern = userPattern;
this.origUser = origUser;
if (origUser.equals(ANY_USER)) {
isAnyUser = true;
}
this.isDomain = isDomain;
this.privSet = privSet;
if (isDomain) {
userIdentity = UserIdentity.createAnalyzedUserIdentWithDomain(origUser, origHost);
} else {
userIdentity = UserIdentity.createAnalyzedUserIdentWithIp(origUser, origHost);
}
}
@Deprecated
public static PrivEntry read(DataInput in) throws IOException {
String className = Text.readString(in);
PrivEntry privEntry = null;
try {
Class<? extends PrivEntry> derivedClass = (Class<? extends PrivEntry>) Class.forName(className);
privEntry = derivedClass.newInstance();
Class[] paramTypes = {DataInput.class};
Method readMethod = derivedClass.getMethod("readFields", paramTypes);
Object[] params = {in};
readMethod.invoke(privEntry, params);
return privEntry;
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException
| SecurityException | IllegalArgumentException | InvocationTargetException e) {
throw new IOException("failed read PrivEntry", e);
}
}
@Deprecated
public void readFields(DataInput in) throws IOException {
origHost = Text.readString(in);
try {
hostPattern = PatternMatcher.createMysqlPattern(origHost, CaseSensibility.HOST.getCaseSensibility());
} catch (PatternMatcherException e) {
throw new IOException(e);
}
isAnyHost = origHost.equals(ANY_HOST);
origUser = Text.readString(in);
try {
userPattern = PatternMatcher.createMysqlPattern(origUser, CaseSensibility.USER.getCaseSensibility());
} catch (PatternMatcherException e) {
throw new IOException(e);
}
isAnyUser = origUser.equals(ANY_USER);
privSet = PrivBitSet.read(in);
isSetByDomainResolver = in.readBoolean();
isDomain = in.readBoolean();
if (isDomain) {
userIdentity = UserIdentity.createAnalyzedUserIdentWithDomain(origUser, origHost);
} else {
userIdentity = UserIdentity.createAnalyzedUserIdentWithIp(origUser, origHost);
}
}
@Deprecated
public boolean match(UserIdentity userIdent, boolean exactMatch) {
if (exactMatch) {
return origUser.equals(userIdent.getQualifiedUser()) && origHost.equals(userIdent.getHost());
} else {
return origUser.equals(userIdent.getQualifiedUser()) && hostPattern.match(userIdent.getHost());
}
}
@Override
public int compareTo(PrivEntry o) {
throw new NotImplementedException("should be implemented by derived class");
}
/**
* Help derived classes compare in the order of 'user', 'host', 'catalog', 'db', 'ctl'.
* Compare strings[i] with strings[i+1] successively, return if the comparison value is not 0 in current loop.
*/
protected static int compareAssist(String... strings) {
Preconditions.checkState(strings.length % 2 == 0);
for (int i = 0; i < strings.length; i += 2) {
int res = strings[i].compareTo(strings[i + 1]);
if (res != 0) {
return res;
}
}
return 0;
}
protected abstract PrivEntry copy() throws AnalysisException, PatternMatcherException;
}