Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.openblocks.domain.bizthreshold;

import static com.openblocks.sdk.util.ExceptionUtils.deferredError;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.openblocks.domain.application.model.ApplicationStatus;
import com.openblocks.domain.application.service.ApplicationService;
import com.openblocks.domain.group.service.GroupService;
import com.openblocks.domain.organization.model.OrgMember;
import com.openblocks.domain.organization.service.OrgMemberService;
import com.openblocks.sdk.exception.BizError;

import reactor.core.publisher.Mono;

@Component
public abstract class AbstractBizThresholdChecker {

@Autowired
private OrgMemberService orgMemberService;

@Autowired
private GroupService groupService;

@Autowired
private ApplicationService applicationService;

protected abstract int getMaxOrgPerUser();

protected abstract int getMaxOrgMemberCount();

protected abstract int getMaxOrgGroupCount();

protected abstract int getMaxOrgAppCount();

protected abstract Map<String, Integer> getUserOrgCountWhiteList();

protected abstract Map<String, Integer> getOrgMemberCountWhiteList();

protected abstract Map<String, Integer> getOrgAppCountWhiteList();

public Mono<Void> checkMaxOrgCount(String userId) {
return orgMemberService.countAllActiveOrgs(userId)
.filter(userOrgCount -> userOrgCountBelowThreshold(userId, userOrgCount))
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_USER_ORG_COUNT, "EXCEED_MAX_USER_ORG_COUNT"))
.then();
}

private boolean userOrgCountBelowThreshold(String userId, long userOrgCount) {
return userOrgCount < Math.max(getUserOrgCountWhiteList().getOrDefault(userId, 0),
getMaxOrgPerUser());
}

public Mono<Void> checkMaxOrgMemberCount(String orgId) {
return orgMemberService.getOrgMemberCount(orgId)
.filter(orgMemberCount -> orgMemberCountBelowThreshold(orgId, orgMemberCount))
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_ORG_MEMBER_COUNT, "EXCEED_MAX_ORG_MEMBER_COUNT"))
.then();
}

private boolean orgMemberCountBelowThreshold(String orgId, Long orgMemberCount) {
return orgMemberCount < Math.max(getMaxOrgMemberCount(), getOrgMemberCountWhiteList().getOrDefault(orgId, 0));
}

public Mono<Void> checkMaxGroupCount(OrgMember orgMemberMono) {
return groupService.getOrgGroupCount(orgMemberMono.getOrgId())
.filter(it -> it < getMaxOrgGroupCount())
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_GROUP_COUNT, "EXCEED_MAX_GROUP_COUNT"))
.then();
}

public Mono<Void> checkMaxOrgApplicationCount(OrgMember orgMember) {
String orgId = orgMember.getOrgId();
return applicationService.countByOrganizationId(orgId, ApplicationStatus.NORMAL)
.filter(orgAppCount -> orgAppCountBelowThreshold(orgId, orgAppCount))
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_APP_COUNT, "EXCEED_MAX_APP_COUNT"))
.then();
}

private boolean orgAppCountBelowThreshold(String orgId, long orgAppCount) {
return orgAppCount < Math.max(getMaxOrgAppCount(), getOrgAppCountWhiteList().getOrDefault(orgId, 0));
}

}
Original file line number Diff line number Diff line change
@@ -1,42 +1,23 @@
package com.openblocks.domain.bizthreshold;

import static com.openblocks.sdk.util.ExceptionUtils.deferredError;

import java.util.Collections;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.openblocks.domain.application.model.ApplicationStatus;
import com.openblocks.domain.application.service.ApplicationService;
import com.openblocks.domain.group.service.GroupService;
import com.openblocks.domain.organization.model.OrgMember;
import com.openblocks.domain.organization.service.OrgMemberService;
import com.openblocks.sdk.config.dynamic.Conf;
import com.openblocks.sdk.config.dynamic.ConfigCenter;
import com.openblocks.sdk.config.dynamic.ConfigInstance;
import com.openblocks.sdk.exception.BizError;

import reactor.core.publisher.Mono;

@Component
public class BizThresholdChecker {

@Autowired
private OrgMemberService orgMemberService;

@Autowired
private GroupService groupService;
@Service
public class BizThresholdChecker extends AbstractBizThresholdChecker {

@Autowired
private ConfigCenter configCenter;

@Autowired
private ApplicationService applicationService;

private Conf<Integer> maxOrgPerUser;
private Conf<Integer> maxOrgMemberCount;
private Conf<Integer> maxOrgGroupCount;
Expand All @@ -50,58 +31,45 @@ private void init() {
ConfigInstance threshold = configCenter.threshold();
maxOrgPerUser = threshold.ofInteger("maxOrgPerUser", 5);
userOrgCountWhiteList = threshold.ofMap("userOrgCountWhiteList", String.class, Integer.class, Collections.emptyMap());

maxOrgMemberCount = threshold.ofInteger("maxOrgMemberCount", 50);
orgMemberCountWhiteList = threshold.ofMap("orgMemberCountWhiteList", String.class, Integer.class, Collections.emptyMap());

maxOrgGroupCount = threshold.ofInteger("maxOrgGroupCount", 10);

maxOrgAppCount = threshold.ofInteger("maxOrgAppCount", 50);
orgAppCountWhiteList = threshold.ofMap("orgAppCountWhiteList", String.class, Integer.class, Collections.emptyMap());
}

public Mono<Void> checkMaxOrgCount(String userId) {
return orgMemberService.countAllActiveOrgs(userId)
.filter(userOrgCount -> userOrgCountBelowThreshold(userId, userOrgCount))
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_USER_ORG_COUNT, "EXCEED_MAX_USER_ORG_COUNT"))
.then();
@Override
protected int getMaxOrgPerUser() {
return maxOrgPerUser.get();
}

private boolean userOrgCountBelowThreshold(String userId, long userOrgCount) {
return userOrgCount < Math.max(userOrgCountWhiteList.get().getOrDefault(userId, 0),
maxOrgPerUser.get());
@Override
protected int getMaxOrgMemberCount() {
return maxOrgMemberCount.get();
}

public Mono<Void> checkMaxOrgMemberCount(String orgId) {
return orgMemberService.getOrgMemberCount(orgId)
.filter(orgMemberCount -> orgMemberCountBelowThreshold(orgId, orgMemberCount))
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_ORG_MEMBER_COUNT, "EXCEED_MAX_ORG_MEMBER_COUNT"))
.then();
@Override
protected int getMaxOrgGroupCount() {
return maxOrgGroupCount.get();
}

private boolean orgMemberCountBelowThreshold(String orgId, Long orgMemberCount) {
return orgMemberCount < Math.max(maxOrgMemberCount.get(), orgMemberCountWhiteList.get().getOrDefault(orgId, 0));
@Override
protected int getMaxOrgAppCount() {
return maxOrgAppCount.get();
}

public Mono<OrgMember> checkMaxGroupCount(Mono<OrgMember> orgMemberMono) {
return orgMemberMono
.flatMap(it -> groupService.getOrgGroupCount(it.getOrgId()))
.filter(it -> it < maxOrgGroupCount.get())
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_GROUP_COUNT, "EXCEED_MAX_GROUP_COUNT"))
.then(orgMemberMono);
@Override
protected Map<String, Integer> getUserOrgCountWhiteList() {
return userOrgCountWhiteList.get();
}


public Mono<Void> checkMaxOrgApplicationCount(OrgMember orgMember) {
String orgId = orgMember.getOrgId();
return applicationService.countByOrganizationId(orgId, ApplicationStatus.NORMAL)
.filter(orgAppCount -> orgAppCountBelowThreshold(orgId, orgAppCount))
.switchIfEmpty(deferredError(BizError.EXCEED_MAX_APP_COUNT, "EXCEED_MAX_APP_COUNT"))
.then();
@Override
protected Map<String, Integer> getOrgMemberCountWhiteList() {
return orgMemberCountWhiteList.get();
}

private boolean orgAppCountBelowThreshold(String orgId, long orgAppCount) {
return orgAppCount < Math.max(maxOrgAppCount.get(), orgAppCountWhiteList.get().getOrDefault(orgId, 0));
@Override
protected Map<String, Integer> getOrgAppCountWhiteList() {
return orgAppCountWhiteList.get();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.openblocks.domain.bizthreshold.BizThresholdChecker;
import com.openblocks.domain.bizthreshold.AbstractBizThresholdChecker;
import com.openblocks.domain.invitation.model.Invitation;
import com.openblocks.domain.invitation.repository.InvitationRepository;
import com.openblocks.domain.organization.model.MemberRole;
Expand All @@ -26,7 +26,7 @@ public class InvitationService {
private OrgMemberService orgMemberService;

@Autowired
private BizThresholdChecker bizThresholdChecker;
private AbstractBizThresholdChecker bizThresholdChecker;

@Autowired
private InvitationRepository repository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ public enum EventType {
GROUP_MEMBER_REMOVE("EVENT_TYPE_GROUP_MEMBER_REMOVE"),
//system
SERVER_START_UP("EVENT_TYPE_SERVER_START_UP"),

// data source
DATA_SOURCE_CREATE("DATA_SOURCE_CREATE"),
DATA_SOURCE_UPDATE("DATA_SOURCE_UPDATE"),
DATA_SOURCE_DELETE("DATA_SOURCE_DELETE"),
DATA_SOURCE_PERMISSION_GRANT("DATA_SOURCE_PERMISSION_GRANT"),
DATA_SOURCE_PERMISSION_UPDATE("DATA_SOURCE_PERMISSION_UPDATE"),
DATA_SOURCE_PERMISSION_DELETE("DATA_SOURCE_PERMISSION_DELETE"),
;

private final String desc;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.openblocks.infra.event.datasource;

import com.openblocks.infra.event.AbstractEvent;
import com.openblocks.infra.event.EventType;

import lombok.Getter;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder
public class DatasourceEvent extends AbstractEvent {

private final String datasourceId;
private final String name;
private final String type;

private final EventType eventType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.openblocks.infra.event.datasource;

import java.util.Collection;

import com.openblocks.infra.event.AbstractEvent;
import com.openblocks.infra.event.EventType;

import lombok.Getter;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder
public class DatasourcePermissionEvent extends AbstractEvent {

private final String datasourceId;
private final String name;
private final String type;

private final Collection<String> userIds;
private final Collection<String> groupIds;
private final String role;

private final EventType eventType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.openblocks.infra.util;

import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RSAUtils {

private static final String algorithm = "RSA";

public static byte[] encrypt(Key key, byte[] data) throws Exception {
final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}

public static byte[] decrypt(Key key, byte[] encryptedData) throws Exception {
final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(encryptedData);
}

public static PublicKey getPublicKey(byte[] encryptedPublicKey) throws Exception {
return KeyFactory.getInstance(algorithm).generatePublic(new X509EncodedKeySpec(encryptedPublicKey));
}

public static PrivateKey getPrivateKey(byte[] encryptedPrivateKey) throws Exception {
return KeyFactory.getInstance(algorithm).generatePrivate(new PKCS8EncodedKeySpec(encryptedPrivateKey));
}

}
6 changes: 6 additions & 0 deletions server/openblocks-sdk/src/main/resources/locale_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ EVENT_TYPE_GROUP_MEMBER_ROLE_UPDATE=Group Member Role Update
EVENT_TYPE_GROUP_MEMBER_LEAVE=Group Member Leave
EVENT_TYPE_GROUP_MEMBER_REMOVE=Group Member Remove
EVENT_TYPE_SERVER_START_UP=Server Startup
DATA_SOURCE_CREATE=Create data source
DATA_SOURCE_UPDATE=Update data source
DATA_SOURCE_DELETE=Delete data source
DATA_SOURCE_PERMISSION_GRANT=Grant data source permissions
DATA_SOURCE_PERMISSION_UPDATE=Update data source permissions
DATA_SOURCE_PERMISSION_DELETE=Delete data source permissions
## threshold
EXCEED_MAX_USER_ORG_COUNT=Sorry, you have reached maximum count of workspaces.
EXCEED_MAX_ORG_MEMBER_COUNT=Sorry, this workspace has reached the maximum count of members.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import com.openblocks.domain.application.model.ApplicationStatus;
import com.openblocks.domain.application.model.ApplicationType;
import com.openblocks.domain.application.service.ApplicationService;
import com.openblocks.domain.bizthreshold.BizThresholdChecker;
import com.openblocks.domain.bizthreshold.AbstractBizThresholdChecker;
import com.openblocks.domain.datasource.model.Datasource;
import com.openblocks.domain.group.service.GroupService;
import com.openblocks.domain.interaction.UserApplicationInteractionService;
Expand Down Expand Up @@ -104,7 +104,7 @@ public class ApplicationApiService {
private UserService userService;

@Autowired
private BizThresholdChecker bizThresholdChecker;
private AbstractBizThresholdChecker bizThresholdChecker;

@Autowired
private TemplateSolution templateSolution;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import java.util.List;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.openblocks.sdk.auth.AbstractAuthConfig;
import com.openblocks.sdk.constants.WorkspaceMode;

Expand All @@ -15,6 +17,7 @@ public class ConfigView {

private boolean isCloudHosting;
private List<AbstractAuthConfig> authConfigs;
private boolean needUpdate;
@JsonInclude(Include.NON_EMPTY)
private String warning;
private WorkspaceMode workspaceMode;
}
Loading