Fix issue #992 - Unable to access OneDev UI if user belongs to login

group
This commit is contained in:
Robin Shen 2022-11-23 15:40:39 +08:00
parent ee44f342db
commit b6f615a001
4 changed files with 119 additions and 22 deletions

View File

@ -10,19 +10,29 @@ import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import com.hazelcast.core.HazelcastInstance;
import io.onedev.server.cluster.ClusterManager;
import io.onedev.server.entitymanager.GroupManager;
import io.onedev.server.entitymanager.IssueFieldManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.event.Listen;
import io.onedev.server.event.entity.EntityPersisted;
import io.onedev.server.event.entity.EntityRemoved;
import io.onedev.server.event.system.SystemStarted;
import io.onedev.server.model.Group;
import io.onedev.server.model.Project;
import io.onedev.server.model.support.BranchProtection;
import io.onedev.server.model.support.TagProtection;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.annotation.Sessional;
import io.onedev.server.persistence.annotation.Transactional;
import io.onedev.server.persistence.dao.BaseEntityManager;
import io.onedev.server.persistence.dao.Dao;
import io.onedev.server.persistence.dao.EntityCriteria;
import io.onedev.server.util.facade.GroupCache;
import io.onedev.server.util.facade.GroupFacade;
import io.onedev.server.util.usage.Usage;
@Singleton
@ -34,13 +44,68 @@ public class DefaultGroupManager extends BaseEntityManager<Group> implements Gro
private final IssueFieldManager issueFieldManager;
private final ClusterManager clusterManager;
private final TransactionManager transactionManager;
private volatile GroupCache cache;
@Inject
public DefaultGroupManager(Dao dao, ProjectManager projectManager, SettingManager settingManager,
IssueFieldManager issueFieldManager) {
IssueFieldManager issueFieldManager, ClusterManager clusterManager,
TransactionManager transactionManager) {
super(dao);
this.projectManager = projectManager;
this.settingManager = settingManager;
this.issueFieldManager = issueFieldManager;
this.clusterManager = clusterManager;
this.transactionManager = transactionManager;
}
@Sessional
@Listen
public void on(SystemStarted event) {
HazelcastInstance hazelcastInstance = clusterManager.getHazelcastInstance();
cache = new GroupCache(hazelcastInstance.getReplicatedMap("groupCache"));
for (Group group: query())
cache.put(group.getId(), group.getFacade());
}
@Transactional
@Listen
public void on(EntityRemoved event) {
if (event.getEntity() instanceof Group) {
Long id = event.getEntity().getId();
transactionManager.runAfterCommit(new Runnable() {
@Override
public void run() {
cache.remove(id);
}
});
}
}
@Transactional
@Listen
public void on(EntityPersisted event) {
if (event.getEntity() instanceof Group)
cacheAfterCommit((Group) event.getEntity());
}
private void cacheAfterCommit(Group group) {
GroupFacade facade = group.getFacade();
transactionManager.runAfterCommit(new Runnable() {
@Override
public void run() {
if (cache != null)
cache.put(facade.getId(), facade);
}
});
}
@Transactional
@ -83,11 +148,12 @@ public class DefaultGroupManager extends BaseEntityManager<Group> implements Gro
@Sessional
@Override
public Group find(String name) {
EntityCriteria<Group> criteria = newCriteria();
criteria.add(Restrictions.ilike("name", name));
criteria.setCacheable(true);
return find(criteria);
public Group find(String groupName) {
GroupFacade facade = cache.find(groupName);
if (facade != null)
return load(facade.getId());
else
return null;
}
@Override

View File

@ -8,15 +8,16 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotEmpty;
import org.apache.shiro.authz.Permission;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.validation.constraints.NotEmpty;
import io.onedev.server.security.permission.CreateRootProjects;
import io.onedev.server.security.permission.ProjectPermission;
import io.onedev.server.util.EditContext;
import io.onedev.server.util.facade.GroupFacade;
import io.onedev.server.web.editable.annotation.Editable;
import io.onedev.server.web.editable.annotation.ShowCondition;
@ -142,6 +143,11 @@ public class Group extends AbstractEntity implements Permission {
return members;
}
@Override
public GroupFacade getFacade() {
return new GroupFacade(getId(), getName());
}
@Override
public int compareTo(AbstractEntity entity) {
Group group = (Group) entity;

View File

@ -1,7 +1,6 @@
package io.onedev.server.model.support.administration;
import java.io.Serializable;
import java.util.Optional;
import javax.annotation.Nullable;
@ -30,8 +29,6 @@ public class SecuritySetting implements Serializable {
private boolean enforce2FA;
private transient Optional<Group> defaultLoginGroup;
@Editable(order=100, description="Whether or not to allow anonymous users to access this server")
public boolean isEnableAnonymousAccess() {
return enableAnonymousAccess;
@ -74,17 +71,12 @@ public class SecuritySetting implements Serializable {
@Nullable
public Group getDefaultLoginGroup() {
if (defaultLoginGroup == null) {
if (defaultLoginGroupName != null) {
Group group = OneDev.getInstance(GroupManager.class).find(defaultLoginGroupName);
if (group == null)
logger.error("Unable to find default login group: " + defaultLoginGroupName);
defaultLoginGroup = Optional.ofNullable(group);
} else {
defaultLoginGroup = Optional.empty();
}
}
return defaultLoginGroup.orElse(null);
return null;
}
public void onRenameGroup(String oldName, String newName) {

View File

@ -0,0 +1,33 @@
package io.onedev.server.util.facade;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import io.onedev.server.util.MapProxy;
public class GroupCache extends MapProxy<Long, GroupFacade> implements Serializable {
private static final long serialVersionUID = 1L;
public GroupCache(Map<Long, GroupFacade> delegate) {
super(delegate);
}
@Nullable
public GroupFacade find(String name) {
for (GroupFacade facade: values()) {
if (name.equals(facade.getName()))
return facade;
}
return null;
}
@Override
public GroupCache clone() {
return new GroupCache(new HashMap<>(delegate));
}
}