All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.security.User Maven / Gradle / Ivy

There is a newer version: 5.10.9
Show newest version
package org.yamcs.security;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.yamcs.security.protobuf.AccountRecord;
import org.yamcs.security.protobuf.Clearance;
import org.yamcs.security.protobuf.ExternalIdentity;
import org.yamcs.security.protobuf.UserAccountRecordDetail;
import org.yamcs.yarch.DataType;
import org.yamcs.yarch.Tuple;

/**
 * A user contains identifying information and a convenient set of methods to perform access control.
 * 

* Users may be assigned two kinds of different privileges: * *

    *
  • System privileges that grant the user the right to perform an action on any object. *
  • Object privileges that grant the user the right to perform an action on a specific object. *
* * Additionally a special attribute {@code superuser} may have been granted to a user. Users with this attribute are not * subjected to privilege checking (i.e. they are allowed everything, even without being assigned privileges). */ public class User extends Account { private String email; private String hash; // Password hash, only for internal users private boolean superuser; private Clearance clearance; private Map identitiesByProvider = new HashMap<>(); // Roles coming from Yamcs DB private Set roles = new HashSet<>(); // Roles that come from external authorization systems private Set externalRoles = new HashSet<>(); // Keep track of external privileges separately. It allows us to rebuild the effective // privileges when the roles change. private Set externalSystemPrivileges = new HashSet<>(); private Map> externalObjectPrivileges = new HashMap<>(); // Effective privileges (= external privileges + privileges from directory roles private Set systemPrivileges = new HashSet<>(); private Map> objectPrivileges = new HashMap<>(); private Set clearanceListeners = new CopyOnWriteArraySet<>(); public User(String username, User createdBy) { super(username, createdBy); } User(AccountRecord record) { super(record); UserAccountRecordDetail userDetail = record.getUserDetail(); if (userDetail.hasHash()) { hash = userDetail.getHash(); } if (userDetail.hasEmail()) { email = userDetail.getEmail(); } superuser = userDetail.getSuperuser(); for (ExternalIdentity identity : userDetail.getIdentitiesList()) { identitiesByProvider.put(identity.getProvider(), identity.getIdentity()); } roles.addAll(userDetail.getRolesList()); if (userDetail.hasClearance()) { clearance = userDetail.getClearance(); } } User(Tuple tuple) { super(tuple); UserAccountRecordDetail userDetail = tuple.getColumn(DirectoryDb.ACCOUNT_CNAME_USER_DETAIL); if (userDetail.hasHash()) { hash = userDetail.getHash(); } if (userDetail.hasEmail()) { email = userDetail.getEmail(); } superuser = userDetail.getSuperuser(); for (ExternalIdentity identity : userDetail.getIdentitiesList()) { identitiesByProvider.put(identity.getProvider(), identity.getIdentity()); } roles.addAll(userDetail.getRolesList()); if (userDetail.hasClearance()) { clearance = userDetail.getClearance(); } } public String getEmail() { return email; } public String getHash() { return hash; } public boolean isExternallyManaged() { return !identitiesByProvider.isEmpty(); } public void addIdentity(String provider, String identity) { identitiesByProvider.put(provider, identity); } public Set> getIdentityEntrySet() { return identitiesByProvider.entrySet(); } public void deleteIdentity(String provider) { identitiesByProvider.remove(provider); } public Clearance getClearance() { return clearance; } public void setClearance(Clearance clearance) { this.clearance = clearance; clearanceListeners.forEach(l -> l.onChange(clearance)); } public Set getRoles() { var merged = new HashSet<>(roles); merged.addAll(externalRoles); return Collections.unmodifiableSet(merged); } public void setRoles(Collection roles) { this.roles.clear(); this.roles.addAll(roles); } /** * Add a role to this user. If marked as external, this role assignment is not persisted to Yamcs DB. */ public void addRole(String role, boolean external) { if (external) { externalRoles.add(role); } else { roles.add(role); } } public void deleteRole(String role) { roles.remove(role); } public boolean isSuperuser() { return superuser; } public void setSuperuser(boolean superuser) { this.superuser = superuser; } public void setEmail(String email) { if (email == null || email.isEmpty()) { this.email = null; } else { this.email = email; } } public void setHash(String hash) { this.hash = hash; } public Set getSystemPrivileges() { return systemPrivileges; } public Map> getObjectPrivileges() { return objectPrivileges; } public Set getObjectPrivileges(ObjectPrivilegeType type) { Set privilegesForType = objectPrivileges.get(type); return privilegesForType != null ? privilegesForType : Collections.emptySet(); } public void addSystemPrivilege(SystemPrivilege systemPrivilege, boolean external) { if (external) { externalSystemPrivileges.add(systemPrivilege); } systemPrivileges.add(systemPrivilege); } public void addObjectPrivilege(ObjectPrivilege objectPrivilege, boolean external) { if (external) { Set externalPrivilegesForType = externalObjectPrivileges.get(objectPrivilege.getType()); if (externalPrivilegesForType == null) { externalPrivilegesForType = new HashSet<>(); externalObjectPrivileges.put(objectPrivilege.getType(), externalPrivilegesForType); } externalPrivilegesForType.add(objectPrivilege); } Set privilegesForType = objectPrivileges.get(objectPrivilege.getType()); if (privilegesForType == null) { privilegesForType = new HashSet<>(); objectPrivileges.put(objectPrivilege.getType(), privilegesForType); } privilegesForType.add(objectPrivilege); } /** * Resets user privileges to only those that are externally defined. */ public void clearDirectoryPrivileges() { systemPrivileges.clear(); systemPrivileges.addAll(externalSystemPrivileges); objectPrivileges.clear(); objectPrivileges.putAll(externalObjectPrivileges); } public boolean hasSystemPrivilege(SystemPrivilege systemPrivilege) { if (superuser) { return true; } return systemPrivileges.contains(systemPrivilege); } public boolean hasObjectPrivilege(ObjectPrivilegeType type, String object) { if (superuser) { return true; } for (ObjectPrivilege privilege : getObjectPrivileges(type)) { if (object.matches(privilege.getObject())) { return true; } } return false; } public void addClearanceListener(ClearanceListener listener) { clearanceListeners.add(listener); } public void removeClearanceListener(ClearanceListener listener) { clearanceListeners.remove(listener); } AccountRecord toRecord() { UserAccountRecordDetail.Builder userDetailb = UserAccountRecordDetail.newBuilder(); if (hash != null) { userDetailb.setHash(hash); } if (email != null) { userDetailb.setEmail(email); } userDetailb.addAllRoles(roles); userDetailb.setSuperuser(superuser); identitiesByProvider.forEach((provider, identity) -> { userDetailb.addIdentities(ExternalIdentity.newBuilder() .setProvider(provider) .setIdentity(identity)); }); if (clearance != null) { userDetailb.setClearance(clearance); } return newRecordBuilder().setUserDetail(userDetailb).build(); } @Override public Tuple toTuple(boolean forUpdate) { var tuple = super.toTuple(forUpdate); var userDetailb = UserAccountRecordDetail.newBuilder(); if (hash != null) { userDetailb.setHash(hash); } if (email != null) { userDetailb.setEmail(email); } userDetailb.addAllRoles(roles); userDetailb.setSuperuser(superuser); identitiesByProvider.forEach((provider, identity) -> { userDetailb.addIdentities(ExternalIdentity.newBuilder() .setProvider(provider) .setIdentity(identity)); }); if (clearance != null) { userDetailb.setClearance(clearance); } tuple.addColumn(DirectoryDb.ACCOUNT_CNAME_USER_DETAIL, DataType.protobuf(UserAccountRecordDetail.class), userDetailb.build()); return tuple; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy