mirror of https://github.com/apache/cloudstack.git
Merge 6c9bc4cfac into 9bbd32a8ef
This commit is contained in:
commit
ded69256f7
|
|
@ -27,11 +27,6 @@ import com.cloud.utils.db.EntityManager;
|
|||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallback;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.api.command.user.gui.theme.CreateGuiThemeCmd;
|
||||
import org.apache.cloudstack.api.command.user.gui.theme.ListGuiThemesCmd;
|
||||
|
|
@ -43,6 +38,7 @@ import org.apache.cloudstack.context.CallContext;
|
|||
import org.apache.cloudstack.gui.theme.dao.GuiThemeDao;
|
||||
import org.apache.cloudstack.gui.theme.dao.GuiThemeDetailsDao;
|
||||
import org.apache.cloudstack.gui.theme.dao.GuiThemeJoinDao;
|
||||
import org.apache.cloudstack.gui.theme.json.config.validator.JsonConfigValidator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
|
@ -52,24 +48,12 @@ import javax.inject.Inject;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public class GuiThemeServiceImpl implements GuiThemeService {
|
||||
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
private static final List<String> ALLOWED_PRIMITIVE_PROPERTIES = List.of("appTitle", "footer", "loginFooter", "logo", "minilogo", "banner");
|
||||
|
||||
private static final List<String> ALLOWED_ERROR_PROPERTIES = List.of("403", "404", "500");
|
||||
|
||||
private static final List<String> ALLOWED_PLUGIN_PROPERTIES = List.of("name", "path", "icon", "isExternalLink");
|
||||
|
||||
private static final String ERROR = "error";
|
||||
|
||||
private static final String PLUGINS = "plugins";
|
||||
|
||||
@Inject
|
||||
GuiThemeDao guiThemeDao;
|
||||
|
||||
|
|
@ -91,6 +75,9 @@ public class GuiThemeServiceImpl implements GuiThemeService {
|
|||
@Inject
|
||||
DomainDao domainDao;
|
||||
|
||||
@Inject
|
||||
JsonConfigValidator jsonConfigValidator;
|
||||
|
||||
@Override
|
||||
public ListResponse<GuiThemeResponse> listGuiThemes(ListGuiThemesCmd cmd) {
|
||||
ListResponse<GuiThemeResponse> response = new ListResponse<>();
|
||||
|
|
@ -244,94 +231,7 @@ public class GuiThemeServiceImpl implements GuiThemeService {
|
|||
|
||||
validateObjectUuids(accountIds, Account.class);
|
||||
validateObjectUuids(domainIds, Domain.class);
|
||||
validateJsonConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
protected void validateJsonConfiguration(String jsonConfig) {
|
||||
if (jsonConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
|
||||
try {
|
||||
JsonElement jsonElement = new JsonParser().parse(jsonConfig);
|
||||
Set<Map.Entry<String, JsonElement>> entries = jsonElement.getAsJsonObject().entrySet();
|
||||
entries.stream().forEach(entry -> validateJsonAttributes(entry, jsonObject));
|
||||
} catch (JsonSyntaxException exception) {
|
||||
logger.error("The following exception was thrown while parsing the JSON object: [{}].", exception.getMessage());
|
||||
throw new CloudRuntimeException("Specified JSON configuration is not a valid JSON object.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the informed JSON attributes considering the allowed properties by the API, any invalid option is ignored.
|
||||
* All valid options are added to a {@link JsonObject} that will be considered as the final JSON configuration used by the GUI theme.
|
||||
*/
|
||||
private void validateJsonAttributes(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
JsonElement entryValue = entry.getValue();
|
||||
String entryKey = entry.getKey();
|
||||
|
||||
if (entryValue.isJsonPrimitive() && ALLOWED_PRIMITIVE_PROPERTIES.contains(entryKey)) {
|
||||
logger.trace("The JSON attribute [{}] is a valid option.", entryKey);
|
||||
jsonObject.add(entryKey, entryValue);
|
||||
} else if (entryValue.isJsonObject() && ERROR.equals(entryKey)) {
|
||||
validateErrorAttribute(entry, jsonObject);
|
||||
} else if (entryValue.isJsonArray() && PLUGINS.equals(entryKey)) {
|
||||
validatePluginsAttribute(entry, jsonObject);
|
||||
} else {
|
||||
warnOfInvalidJsonAttribute(entryKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link JsonObject} with only the valid options for the Plugins' properties specified in the {@link #ALLOWED_PLUGIN_PROPERTIES}.
|
||||
*/
|
||||
protected void validatePluginsAttribute(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
Set<Map.Entry<String, JsonElement>> entries = entry.getValue().getAsJsonArray().get(0).getAsJsonObject().entrySet();
|
||||
JsonObject objectToBeAdded = createJsonObject(entries, ALLOWED_PLUGIN_PROPERTIES);
|
||||
JsonArray jsonArray = new JsonArray();
|
||||
|
||||
if (objectToBeAdded.entrySet().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsonArray.add(objectToBeAdded);
|
||||
jsonObject.add(entry.getKey(), jsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link JsonObject} with only the valid options for the Error's properties specified in the {@link #ALLOWED_ERROR_PROPERTIES}.
|
||||
*/
|
||||
protected void validateErrorAttribute(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
Set<Map.Entry<String, JsonElement>> entries = entry.getValue().getAsJsonObject().entrySet();
|
||||
JsonObject objectToBeAdded = createJsonObject(entries, ALLOWED_ERROR_PROPERTIES);
|
||||
|
||||
if (objectToBeAdded.entrySet().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsonObject.add(entry.getKey(), objectToBeAdded);
|
||||
}
|
||||
|
||||
protected JsonObject createJsonObject(Set<Map.Entry<String, JsonElement>> entries, List<String> allowedProperties) {
|
||||
JsonObject objectToBeAdded = new JsonObject();
|
||||
|
||||
for (Map.Entry<String, JsonElement> recursiveEntry : entries) {
|
||||
String entryKey = recursiveEntry.getKey();
|
||||
|
||||
if (!allowedProperties.contains(entryKey)) {
|
||||
warnOfInvalidJsonAttribute(entryKey);
|
||||
continue;
|
||||
}
|
||||
objectToBeAdded.add(entryKey, recursiveEntry.getValue());
|
||||
}
|
||||
|
||||
return objectToBeAdded;
|
||||
}
|
||||
|
||||
protected void warnOfInvalidJsonAttribute(String entryKey) {
|
||||
logger.warn("The JSON attribute [{}] is not a valid option, therefore, it will be ignored.", entryKey);
|
||||
jsonConfigValidator.validateJsonConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface JsonConfigAttributeValidator {
|
||||
|
||||
void validate(Map.Entry<String, JsonElement> entry, JsonObject jsonObject);
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class JsonConfigValidator {
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
private static final List<String> ALLOWED_PRIMITIVE_PROPERTIES = List.of("appTitle", "footer", "loginFooter", "logo", "minilogo", "banner", "docBase", "apidocs");
|
||||
private static final List<String> ALLOWED_DYNAMIC_PROPERTIES = List.of("error", "theme", "plugins", "keyboardOptions", "userCard", "docHelpMappings");
|
||||
|
||||
@Inject
|
||||
private List<JsonConfigAttributeValidator> attributes;
|
||||
|
||||
public void validateJsonConfiguration(String jsonConfig) {
|
||||
if (StringUtils.isBlank(jsonConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
|
||||
try {
|
||||
JsonElement jsonElement = JsonParser.parseString(jsonConfig);
|
||||
Set<Map.Entry<String, JsonElement>> entries = jsonElement.getAsJsonObject().entrySet();
|
||||
entries.forEach(entry -> validateJsonAttributes(entry, jsonObject));
|
||||
} catch (JsonSyntaxException exception) {
|
||||
logger.error("The following exception was thrown while parsing the JSON object: [{}].", exception.getMessage());
|
||||
throw new CloudRuntimeException("Specified JSON configuration is not a valid JSON object.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the informed JSON attributes considering the allowed properties by the API, any invalid option is ignored.
|
||||
* All valid options are added to a {@link JsonObject} that will be considered as the final JSON configuration used by the GUI theme.
|
||||
*/
|
||||
private void validateJsonAttributes(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
JsonElement entryValue = entry.getValue();
|
||||
String entryKey = entry.getKey();
|
||||
|
||||
if (entryValue.isJsonPrimitive() && ALLOWED_PRIMITIVE_PROPERTIES.contains(entryKey)) {
|
||||
logger.trace("The JSON attribute [{}] is a valid option.", entryKey);
|
||||
jsonObject.add(entryKey, entryValue);
|
||||
} else if (ALLOWED_DYNAMIC_PROPERTIES.contains(entryKey)) {
|
||||
attributes.forEach(attribute -> attribute.validate(entry, jsonObject));
|
||||
} else {
|
||||
logger.warn("The JSON attribute [{}] is not a valid option, therefore, it will be ignored.", entryKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator.attributes;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.cloudstack.gui.theme.json.config.validator.JsonConfigAttributeValidator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class AttributeBase implements JsonConfigAttributeValidator {
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
protected abstract String getAttributeName();
|
||||
protected abstract List<String> getAllowedProperties();
|
||||
|
||||
@Override
|
||||
public void validate(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
if (!getAttributeName().equals(entry.getKey())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Map.Entry<String, JsonElement>> entries = entry.getValue().getAsJsonObject().entrySet();
|
||||
JsonObject objectToBeAdded = createJsonObject(entries, getAllowedProperties());
|
||||
|
||||
if (!objectToBeAdded.entrySet().isEmpty()) {
|
||||
jsonObject.add(entry.getKey(), objectToBeAdded);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link JsonObject} with only the valid options for the attribute properties specified in the allowedProperties parameter.
|
||||
*/
|
||||
public JsonObject createJsonObject(Set<Map.Entry<String, JsonElement>> entries, List<String> allowedProperties) {
|
||||
JsonObject objectToBeAdded = new JsonObject();
|
||||
|
||||
for (Map.Entry<String, JsonElement> recursiveEntry : entries) {
|
||||
String entryKey = recursiveEntry.getKey();
|
||||
|
||||
if (!allowedProperties.contains(entryKey)) {
|
||||
warnOfInvalidJsonAttribute(entryKey);
|
||||
continue;
|
||||
}
|
||||
objectToBeAdded.add(entryKey, recursiveEntry.getValue());
|
||||
}
|
||||
|
||||
logger.trace("JSON object with valid options: {}.", objectToBeAdded);
|
||||
return objectToBeAdded;
|
||||
}
|
||||
|
||||
protected void warnOfInvalidJsonAttribute(String entryKey) {
|
||||
logger.warn("The JSON attribute [{}] is not a valid option, therefore, it will be ignored.", entryKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator.attributes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ErrorAttribute extends AttributeBase {
|
||||
|
||||
@Override
|
||||
protected String getAttributeName() {
|
||||
return "error";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getAllowedProperties() {
|
||||
return List.of("403", "404", "500");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator.attributes;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class PluginsAttribute extends AttributeBase {
|
||||
|
||||
@Override
|
||||
protected String getAttributeName() {
|
||||
return "plugins";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getAllowedProperties() {
|
||||
return List.of("name", "path", "icon", "isExternalLink");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
if (!getAttributeName().equals(entry.getKey())) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonArray jsonArrayResult = new JsonArray();
|
||||
JsonArray sourceJsonArray = entry.getValue().getAsJsonArray();
|
||||
for (JsonElement jsonElement : sourceJsonArray) {
|
||||
Set<Map.Entry<String, JsonElement>> pluginEntries = jsonElement.getAsJsonObject().entrySet();
|
||||
JsonObject pluginObjectToBeAdded = createJsonObject(pluginEntries, getAllowedProperties());
|
||||
|
||||
if (pluginObjectToBeAdded.entrySet().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsonArrayResult.add(pluginObjectToBeAdded);
|
||||
}
|
||||
|
||||
jsonObject.add(entry.getKey(), jsonArrayResult);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator.attributes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ThemeAttribute extends AttributeBase {
|
||||
|
||||
@Override
|
||||
protected String getAttributeName() {
|
||||
return "theme";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getAllowedProperties() {
|
||||
return List.of("@layout-mode", "@logo-background-color", "@mini-logo-background-color", "@navigation-background-color",
|
||||
"@project-nav-background-color", "@project-nav-text-color", "@navigation-text-color", "@primary-color", "@link-color", "@link-hover-color", "@loading-color", "@processing-color",
|
||||
"@success-color", "@warning-color", "@error-color", "@font-size-base", "@heading-color", "@text-color", "@text-color-secondary", "@disabled-color", "@border-color-base", "@border-radius-base",
|
||||
"@box-shadow-base", "@logo-width", "@logo-height", "@mini-logo-width", "@mini-logo-height", "@banner-width", "@banner-height", "@error-width", "@error-height");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// 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.cloudstack.gui.theme.json.config.validator.attributes;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class UserCardAttribute extends AttributeBase {
|
||||
private static final List<String> ALLOWED_USER_CARD_LINKS_PROPERTIES = List.of("title", "text", "link", "icon");
|
||||
private static final String LINKS = "links";
|
||||
|
||||
@Override
|
||||
protected String getAttributeName() {
|
||||
return "userCard";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getAllowedProperties() {
|
||||
return List.of("title", "icon", "links");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
if (!getAttributeName().equals(entry.getKey())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Map.Entry<String, JsonElement>> entries = entry.getValue().getAsJsonObject().entrySet();
|
||||
JsonObject objectToBeAdded = new JsonObject();
|
||||
for (Map.Entry<String, JsonElement> recursiveEntry : entries) {
|
||||
String entryKey = recursiveEntry.getKey();
|
||||
|
||||
if (!getAllowedProperties().contains(entryKey)) {
|
||||
warnOfInvalidJsonAttribute(entryKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LINKS.equals(entryKey)) {
|
||||
createLinkJsonObject(recursiveEntry, jsonObject);
|
||||
}
|
||||
|
||||
objectToBeAdded.add(entryKey, recursiveEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void createLinkJsonObject(Map.Entry<String, JsonElement> entry, JsonObject jsonObject) {
|
||||
JsonArray jsonArrayResult = new JsonArray();
|
||||
JsonArray sourceJsonArray = entry.getValue().getAsJsonArray();
|
||||
for (JsonElement jsonElement : sourceJsonArray) {
|
||||
Set<Map.Entry<String, JsonElement>> linkEntries = jsonElement.getAsJsonObject().entrySet();
|
||||
JsonObject linkObjectToBeAdded = createJsonObject(linkEntries, ALLOWED_USER_CARD_LINKS_PROPERTIES);
|
||||
|
||||
if (linkObjectToBeAdded.entrySet().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsonArrayResult.add(linkObjectToBeAdded);
|
||||
}
|
||||
jsonObject.add(entry.getKey(), jsonArrayResult);
|
||||
}
|
||||
}
|
||||
|
|
@ -83,4 +83,9 @@
|
|||
|
||||
<bean id="domainHelper" class="com.cloud.utils.DomainHelper" />
|
||||
|
||||
<bean id="jsonConfigValidator" class="org.apache.cloudstack.gui.theme.json.config.validator.JsonConfigValidator" />
|
||||
<bean id="errorAttribute" class="org.apache.cloudstack.gui.theme.json.config.validator.attributes.ErrorAttribute" />
|
||||
<bean id="pluginsAttribute" class="org.apache.cloudstack.gui.theme.json.config.validator.attributes.PluginsAttribute" />
|
||||
<bean id="themeAttribute" class="org.apache.cloudstack.gui.theme.json.config.validator.attributes.ThemeAttribute" />
|
||||
<bean id="userCardAttribute" class="org.apache.cloudstack.gui.theme.json.config.validator.attributes.UserCardAttribute" />
|
||||
</beans>
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ export default {
|
|||
this.parentToggleSetting(false)
|
||||
},
|
||||
downloadSetting () {
|
||||
this.downloadObjectAsJson(this.uiSettings)
|
||||
this.downloadObjectAsJson(this.$config.theme)
|
||||
},
|
||||
resetSetting () {
|
||||
this.uiSettings = {}
|
||||
|
|
|
|||
|
|
@ -69,12 +69,14 @@ async function applyDynamicCustomization (response) {
|
|||
vueProps.$config.logo = jsonConfig?.logo ?? vueProps.$config.logo
|
||||
vueProps.$config.minilogo = jsonConfig?.minilogo ?? vueProps.$config.minilogo
|
||||
vueProps.$config.banner = jsonConfig?.banner ?? vueProps.$config.banner
|
||||
vueProps.$config.docBase = jsonConfig?.docBase ?? vueProps.$config.docBase
|
||||
vueProps.$config.apidocs = jsonConfig?.apidocs ?? vueProps.$config.apidocs
|
||||
vueProps.$config.docHelpMappings = jsonConfig?.docHelpMappings ?? vueProps.$config.docHelpMappings
|
||||
vueProps.$config.keyboardOptions = jsonConfig?.keyboardOptions ?? vueProps.$config.keyboardOptions
|
||||
|
||||
if (jsonConfig?.error) {
|
||||
vueProps.$config.error[403] = jsonConfig?.error[403] ?? vueProps.$config.error[403]
|
||||
vueProps.$config.error[404] = jsonConfig?.error[404] ?? vueProps.$config.error[404]
|
||||
vueProps.$config.error[500] = jsonConfig?.error[500] ?? vueProps.$config.error[500]
|
||||
}
|
||||
applyJsonConfigToObject(jsonConfig?.error, vueProps.$config.error)
|
||||
applyJsonConfigToObject(jsonConfig?.userCard, vueProps.$config.userCard)
|
||||
applyJsonConfigToObject(jsonConfig?.theme, vueProps.$config.theme)
|
||||
|
||||
if (jsonConfig?.plugins) {
|
||||
jsonConfig.plugins.forEach(plugin => {
|
||||
|
|
@ -82,12 +84,27 @@ async function applyDynamicCustomization (response) {
|
|||
})
|
||||
}
|
||||
|
||||
if (vueProps.$store) {
|
||||
vueProps.$store.dispatch('SetDarkMode', (vueProps.$config.theme['@layout-mode'] === 'dark'))
|
||||
}
|
||||
window.less.modifyVars(vueProps.$config.theme)
|
||||
|
||||
vueProps.$config.favicon = jsonConfig?.favicon ?? vueProps.$config.favicon
|
||||
vueProps.$config.css = response?.css ?? null
|
||||
|
||||
await applyStaticCustomization(vueProps.$config.favicon, vueProps.$config.css)
|
||||
}
|
||||
|
||||
function applyJsonConfigToObject (sourceConfig, targetObject) {
|
||||
if (!sourceConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const [variableName, value] of Object.entries(targetObject)) {
|
||||
targetObject[variableName] = sourceConfig?.[variableName] ?? value
|
||||
}
|
||||
}
|
||||
|
||||
async function applyStaticCustomization (favicon, css) {
|
||||
document.getElementById('favicon').href = favicon
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue