org.exist.security.AbstractAccount Maven / Gradle / Ivy
/*
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
* [email protected]
* http://www.exist-db.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.exist.security;
import java.util.*;
import org.exist.config.Configuration;
import org.exist.config.ConfigurationException;
import org.exist.config.annotation.ConfigurationClass;
import org.exist.config.annotation.ConfigurationFieldAsElement;
import org.exist.config.annotation.ConfigurationFieldSettings;
import static org.exist.config.annotation.ConfigurationFieldSettings.OCTAL_STRING_KEY;
import org.exist.config.annotation.ConfigurationReferenceBy;
import org.exist.storage.DBBroker;
@ConfigurationClass("")
public abstract class AbstractAccount extends AbstractPrincipal implements Account {
@ConfigurationFieldAsElement("group")
@ConfigurationReferenceBy("name")
protected List groups = new ArrayList<>();
//used for internal locking
private boolean accountLocked = false;
@ConfigurationFieldAsElement("expired")
private boolean accountExpired = false;
//@ConfigurationFieldAsElement("credentials-expired")
private boolean credentialsExpired = false;
@ConfigurationFieldAsElement("enabled")
private boolean enabled = true;
@ConfigurationFieldAsElement("umask")
@ConfigurationFieldSettings(OCTAL_STRING_KEY)
private int umask = Permission.DEFAULT_UMASK;
@ConfigurationFieldAsElement("metadata")
private Map metadata = new HashMap<>();
protected Credential _cred = null;
/**
* Indicates if the user belongs to the dba group, i.e. is a superuser.
*/
protected boolean hasDbaRole = false;
protected AbstractAccount(final DBBroker broker, final AbstractRealm realm, final int id, final String name) throws ConfigurationException {
super(broker, realm, realm.collectionAccounts, id, name);
}
public AbstractAccount(final AbstractRealm realm, final Configuration configuration) throws ConfigurationException {
super(realm, configuration);
}
public boolean checkCredentials(final Object credentials) {
return _cred == null ? false : _cred.check(credentials);
}
@Override
public Group addGroup(final String name) throws PermissionDeniedException {
Group group = getRealm().getGroup(name);
//if we cant find the group in our own realm, try other realms
if(group == null) {
group = getRealm().getSecurityManager().getGroup(name);
}
return addGroup(group);
}
//this method is used by Configurator
protected final Group addGroup(final Configuration conf) throws PermissionDeniedException {
if (conf == null) {
return null;
}
final String name = conf.getProperty("name");
if (name == null) {
return null;
}
return addGroup(name);
}
@Override
public Group addGroup(final Group group) throws PermissionDeniedException {
if(group == null){
return null;
}
final Account user = getDatabase().getActiveBroker().getCurrentSubject();
group.assertCanModifyGroup(user);
if(!groups.contains(group)) {
groups.add(group);
if(SecurityManager.DBA_GROUP.equals(group.getName())) {
hasDbaRole = true;
}
}
return group;
}
@Override
public void setPrimaryGroup(final Group group) throws PermissionDeniedException {
final Account user = getDatabase().getActiveBroker().getCurrentSubject();
group.assertCanModifyGroup(user);
if(!groups.contains(group)) {
addGroup(group);
}
groups.sort((final Group o1, final Group o2) -> {
if (o1.getName().equals(group.getName())) {
return -1;
} else {
return 1;
}
});
}
@Override
public final void remGroup(final String name) throws PermissionDeniedException {
final Account subject = getDatabase().getActiveBroker().getCurrentSubject();
for (final Group group : groups) {
if (group.getName().equals(name)) {
group.assertCanModifyGroup(subject);
if (groups.size() <= 1) {
throw new PermissionDeniedException("You cannot remove the primary group of an account.");
}
//remove from the group
groups.remove(group);
break;
}
}
if(SecurityManager.DBA_GROUP.equals(name)){
hasDbaRole = false;
}
}
@Override
public final void setGroups(final String[] groups) {
// this.groups = groups;
// for (int i = 0; i < groups.length; i++)
// if (SecurityManager.DBA_GROUP.equals(groups[i]))
// hasDbaRole = true;
}
@Override
public String[] getGroups() {
if (groups == null) {
return new String[0];
}
int i = 0;
final String[] names = new String[groups.size()];
for (final Group role : groups) {
names[i++] = role.getName();
}
return names;
}
@Override
public int[] getGroupIds() {
if(groups == null) {
return new int[0];
}
int i = 0;
final int[] ids = new int[groups.size()];
for (final Group group : groups) {
ids[i++] = group.getId();
}
return ids;
}
@Override
public final boolean hasGroup(final String name) {
if (groups == null) {
return false;
}
for (final Group group : groups) {
if (group.getName().equals(name)) {
return true;
}
}
return false;
}
@Override
public final boolean hasDbaRole() {
return hasDbaRole;
}
@Override
public final String toString() {
final StringBuilder buf = new StringBuilder();
buf.append("");
if (groups != null) {
for (final Group group : groups) {
buf.append(group.toString());
}
}
buf.append(" ");
return buf.toString();
}
@Override
public boolean equals(final Object obj) {
return Optional
.ofNullable(obj)
.flatMap(other -> {
if(other instanceof AbstractSubject) {
return Optional.of(((AbstractSubject)other).account);
} else if(other instanceof AbstractAccount) {
return Optional.of((AbstractAccount)other);
} else {
return Optional.empty();
}
}).map(otherAccount -> getRealm().equals(otherAccount.getRealm()) && name.equals(otherAccount.name))
.orElse(false);
}
@Override
public final String getPrimaryGroup() {
//TODO this function should return Group and not String
final Group defaultGroup = getDefaultGroup();
if(defaultGroup != null) {
return defaultGroup.getName();
} else {
return null;
}
}
/**
* @deprecated user getPrimaryGroup instead;
*/
@Deprecated
@Override
public Group getDefaultGroup() {
if(groups != null && !groups.isEmpty()) {
return groups.get(0);
}
return null;
}
@Override
public String getUsername() {
return getName();
}
@Override
public boolean isAccountNonExpired() {
return !accountExpired;
}
@Override
public boolean isAccountNonLocked() {
return !accountLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return !credentialsExpired;
}
@Override
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public String getMetadataValue(final SchemaType schemaType) {
return metadata.get(schemaType.getNamespace());
}
@Override
public void setMetadataValue(final SchemaType schemaType, final String value) {
metadata.put(schemaType.getNamespace(), value);
}
@Override
public Set getMetadataKeys() {
final Set metadataKeys = new HashSet<>();
for(final String key : metadata.keySet()) {
//XXX: other types?
if(AXSchemaType.valueOfNamespace(key) != null) {
metadataKeys.add(AXSchemaType.valueOfNamespace(key));
} else if(EXistSchemaType.valueOfNamespace(key) != null){
metadataKeys.add(EXistSchemaType.valueOfNamespace(key));
}
}
return metadataKeys;
}
@Override
public void clearMetadata() {
if(metadata != null) {
this.metadata.clear();
}
}
@Override
public void assertCanModifyAccount(final Account user) throws PermissionDeniedException {
if(user == null) {
throw new PermissionDeniedException("Unspecified User is not allowed to modify account '" + getName() + "'");
} else if(!user.hasDbaRole() && !user.getName().equals(getName())) {
throw new PermissionDeniedException("User '" + user.getName() + "' is not allowed to modify account '" + getName() + "'");
}
}
@Override
public void setUserMask(final int umask) {
this.umask = umask;
}
@Override
public int getUserMask() {
return umask;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy