1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2025-12-01 09:06:43 +02:00

#546 - Функция "РольДоступна" ссылается на несуществующую роль конфигурации (#1274)

This commit is contained in:
Vadim Goncharov
2023-04-18 01:11:07 +03:00
committed by GitHub
parent ea1029c0ae
commit f4777c5ae9
23 changed files with 450 additions and 0 deletions

View File

@@ -33,6 +33,7 @@
- Обращение к несуществующему параметру формы
- Необязательный параметр процедуры/функции стоит перед обязательным
- Обращение к опциональному параметру формы
- Функция "РольДоступна" ссылается на несуществующие роли
#### Запросы

View File

@@ -39,6 +39,7 @@ Import-Package: com._1c.g5.v8.bm.core;version="[7.0.0,8.0.0)",
com._1c.g5.v8.dt.bsl.util;version="[7.0.0,8.0.0)",
com._1c.g5.v8.dt.bsl.validation;version="[16.0.0,17.0.0)",
com._1c.g5.v8.dt.common;version="[6.0.0,7.0.0)",
com._1c.g5.v8.dt.core.naming;version="[6.0.0,7.0.0)",
com._1c.g5.v8.dt.core.platform;version="[10.0.0,11.0.0)",
com._1c.g5.v8.dt.form.model;version="[11.0.0,12.0.0)",
com._1c.g5.v8.dt.lcore.ui.editor;version="[2.3.0,3.0.0)",

View File

@@ -0,0 +1,11 @@
# Referring to a non-existent role
In the parameter of the function "IsInRole" must existing role to be specified.
## Noncompliant Code Example
## Compliant Solution
## See

View File

@@ -0,0 +1,11 @@
# Обращение к несуществующей роли
В параметре функции "РольДоступна" должна быть указана существующая роль.
## Неправильно
## Правильно
## См.

View File

@@ -347,6 +347,10 @@
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.DeprecatedProcedureOutsideDeprecatedRegionCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.IsInRoleMethodRoleExistCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.MethodOptionalParameterBeforeRequiredCheck">

View File

@@ -0,0 +1,160 @@
/*******************************************************************************
* Copyright (C) 2023, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.INVOCATION;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.STRING_LITERAL__LINES;
import static com._1c.g5.v8.dt.metadata.mdclass.MdClassPackage.Literals.CONFIGURATION__ROLES;
import static com._1c.g5.v8.dt.metadata.mdclass.MdClassPackage.Literals.ROLE;
import java.text.MessageFormat;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.IScopeProvider;
import com._1c.g5.v8.dt.bsl.model.Expression;
import com._1c.g5.v8.dt.bsl.model.Invocation;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
import com._1c.g5.v8.dt.bsl.model.StringLiteral;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.core.naming.ITopObjectFqnGenerator;
import com.e1c.g5.v8.dt.check.CheckComplexity;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.e1c.v8codestyle.check.CommonSenseCheckExtension;
import com.e1c.v8codestyle.internal.bsl.BslPlugin;
import com.google.inject.Inject;
/**
* Check the method IsInRole, that first param contains exists roles.
* @author Vadim Goncharov
*/
public class IsInRoleMethodRoleExistCheck
extends BasicCheck
{
private static final String CHECK_ID = "method-isinrole-role-exist"; //$NON-NLS-1$
private static final String METHOD_ISINROLE_NAME = "IsInRole"; //$NON-NLS-1$
private static final String METHOD_ISINROLE_NAME_RU = "РольДоступна"; //$NON-NLS-1$
private final IScopeProvider scopeProvider;
private final IQualifiedNameConverter qualifiedNameConverter;
private final ITopObjectFqnGenerator topObjectFqnGenerator;
/**
* Instantiates a new invocation role check access exist role check.
*
* @param scopeProvider the scope provider
* @param qualifiedNameConverter the qualified name converter
* @param topObjectFqnGenerator the top object fqn generator
*/
@Inject
public IsInRoleMethodRoleExistCheck(IScopeProvider scopeProvider, IQualifiedNameConverter qualifiedNameConverter,
ITopObjectFqnGenerator topObjectFqnGenerator)
{
super();
this.scopeProvider = scopeProvider;
this.qualifiedNameConverter = qualifiedNameConverter;
this.topObjectFqnGenerator = topObjectFqnGenerator;
}
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.IsInRoleMethodRoleExistCheck_title)
.description(Messages.IsInRoleMethodRoleExistCheck_description)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MAJOR)
.issueType(IssueType.WARNING)
.extension(new CommonSenseCheckExtension(getCheckId(), BslPlugin.PLUGIN_ID))
.module()
.checkedObjectType(INVOCATION);
}
@Override
protected void check(Object object, ResultAcceptor resultAcceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
Invocation inv = (Invocation)object;
if (monitor.isCanceled() || !isValidInvocation(inv))
{
return;
}
EList<Expression> params = inv.getParams();
if (monitor.isCanceled() || params.isEmpty() || !(params.get(0) instanceof StringLiteral))
{
return;
}
StringLiteral literal = (StringLiteral)params.get(0);
String roleName = literal.lines(true).get(0);
if (StringUtils.isEmpty(roleName))
{
return;
}
IEObjectDescription roleDesc = getRoleDescFromScope(inv, roleName);
if (!monitor.isCanceled() && roleDesc == null)
{
String message = MessageFormat
.format(Messages.IsInRoleMethodRoleExistCheck_Role_named_not_exists_in_configuration, roleName);
resultAcceptor.addIssue(message, literal, STRING_LITERAL__LINES);
}
}
private boolean isValidInvocation(Invocation invocation)
{
if (invocation.getMethodAccess() instanceof StaticFeatureAccess)
{
StaticFeatureAccess sfa = (StaticFeatureAccess)invocation.getMethodAccess();
if (sfa.getName().equalsIgnoreCase(METHOD_ISINROLE_NAME)
|| sfa.getName().equalsIgnoreCase(METHOD_ISINROLE_NAME_RU))
{
return true;
}
}
return false;
}
private IEObjectDescription getRoleDescFromScope(Invocation inv, String roleName)
{
IScope scope = scopeProvider.getScope(inv, CONFIGURATION__ROLES);
String fqn = topObjectFqnGenerator.generateStandaloneObjectFqn(ROLE, roleName);
return scope.getSingleElement(qualifiedNameConverter.toQualifiedName(fqn));
}
}

View File

@@ -440,6 +440,12 @@ final class Messages
public static String IsInRoleCheck_Using_IsInRole;
public static String IsInRoleMethodRoleExistCheck_description;
public static String IsInRoleMethodRoleExistCheck_Role_named_not_exists_in_configuration;
public static String IsInRoleMethodRoleExistCheck_title;
public static String ModuleUndefinedVariableCheck_Title;
public static String ModuleUndefinedVariableCheck_Description;
public static String ModuleUndefinedVariable_msg;

View File

@@ -216,6 +216,12 @@ IsInRoleCheck_Use_AccessRight_instead_IsInRole = Use the AccessRight() function
IsInRoleCheck_Using_IsInRole = Using "IsInRole" method
IsInRoleMethodRoleExistCheck_Role_named_not_exists_in_configuration=Role named {0} not exists in configuration
IsInRoleMethodRoleExistCheck_description=Referring to a non-existent role
IsInRoleMethodRoleExistCheck_title=Referring to a non-existent role
LockOutOfTry_Checks_for_init_of_the_data_lock = Checks for initialization of the data lock. If the creation of a lock is found, the call of the Lock() method is checked, and the call must be in a try.
LockOutOfTry_Lock_out_of_try = Lock out of Try

View File

@@ -216,6 +216,12 @@ IsInRoleCheck_Use_AccessRight_instead_IsInRole = Используйте функ
IsInRoleCheck_Using_IsInRole = Использован не рекомендованный метод "РольДоступна"
IsInRoleMethodRoleExistCheck_Role_named_not_exists_in_configuration = Роль {0} не существует в конфигурации
IsInRoleMethodRoleExistCheck_description = Обращение к несуществующей роли
IsInRoleMethodRoleExistCheck_title = Обращение к несуществующей роли
LockOutOfTry_Checks_for_init_of_the_data_lock = Правило проверяет наличие инициализации блокировки данных. В случае если найдено создание блокировки, проверяется вызов метода "Заблокировать()", при этом вызов должен быть в попытке.
LockOutOfTry_Lock_out_of_try = Метод Заблокировать() вне блока Попытка-Исключение

View File

@@ -43,6 +43,7 @@ import com._1c.g5.v8.dt.platform.version.IRuntimeVersionSupport;
import com._1c.g5.wiring.AbstractServiceAwareModule;
import com.e1c.g5.v8.dt.check.qfix.IFixRepository;
import com.e1c.g5.v8.dt.check.settings.ICheckRepository;
import com._1c.g5.v8.dt.core.naming.ITopObjectFqnGenerator;
/**
* The external dependencies for plugin
@@ -67,6 +68,7 @@ class ExternalDependenciesModule
bind(IBslPreferences.class).toService();
bind(IQualifiedNameConverter.class).toService();
bind(IBslModuleContextDefService.class).toService();
bind(ITopObjectFqnGenerator.class).toService();
bind(ICheckRepository.class).toService();
bind(IFixRepository.class).toService();

View File

@@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (C) 2023, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.Path;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.IExtraInfoKeys;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.IsInRoleMethodRoleExistCheck;
/**
* The test for {@link IsInRoleMethodRoleExistCheck} class.
* @author Vadim Goncharov
*/
public class IsInRoleMethodRoleExistCheckTest
extends AbstractSingleModuleTestBase
{
private static final String PROJECT_NAME = "IsInRoleMethodRoleExist"; //$NON-NLS-1$
private static final String COMMON_MODULE_FILE_NAME = "/src/CommonModules/RolesCommonModule/Module.bsl"; //$NON-NLS-1$
public IsInRoleMethodRoleExistCheckTest()
{
super(IsInRoleMethodRoleExistCheck.class);
}
@Override
protected String getTestConfigurationName()
{
return PROJECT_NAME;
}
@Override
protected String getModuleFileName()
{
return COMMON_MODULE_FILE_NAME;
}
/**
* Test invocation role check access exist role check.
*
* @throws Exception the exception
*/
@Test
public void testIsInRoleMethodRoleExistCheck() throws Exception
{
List<Marker> markers = getModuleMarkers();
assertEquals(2, markers.size());
assertEquals("2", markers.get(0).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("9", markers.get(1).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>IsInRoleMethodRoleExist</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
<nature>com._1c.g5.v8.dt.core.V8ConfigurationNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@@ -0,0 +1,2 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.19

View File

@@ -0,0 +1,19 @@
Procedure TestIsInRole()
If IsInRole("TestRole3") Then
EndIf;
If IsInRole("TestRole1") Then
EndIf;
EndProcedure
Процедура ТестРольДоступна()
Если РольДоступна("TestRole3") Тогда
КонецЕсли;
Если РольДоступна("TestRole1") Тогда
КонецЕсли;
КонецПроцедуры
Procedure TestStaff()
If Users.RolesAvailable("TestRole1,TestRole2,TestRole3") Then
Message("Test message");
EndIf;
EndProcedure

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="6f749273-bdc4-4395-bcf0-a26399389210">
<name>RolesCommonModule</name>
<synonym>
<key>en</key>
<value>Roles common module</value>
</synonym>
<server>true</server>
</mdclass:CommonModule>

View File

@@ -0,0 +1,8 @@
Function RolesAvailable(RolesNames, User = Undefined, ForPrivilegedMode = True) Export
//Some checks
Return True;
EndFunction
Function IsFullUser(User = Undefined) Export
Return True;
EndFunction

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="72701a84-135e-494e-b68f-f287fb81c335">
<name>Users</name>
<synonym>
<key>en</key>
<value>Users</value>
</synonym>
<server>true</server>
</mdclass:CommonModule>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Configuration xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="94ce6be4-4189-4a62-85af-1d9e391d338a">
<name>IsInRoleMethodRoleExist</name>
<synonym>
<key>en</key>
<value>IsInRoleMethodRoleExistCheck</value>
</synonym>
<containedObjects classId="9cd510cd-abfc-11d4-9434-004095e12fc7" objectId="cfa3e992-f719-4203-af07-9f7c4f155fb0"/>
<containedObjects classId="9fcd25a0-4822-11d4-9414-008048da11f9" objectId="1976c333-6fbe-408d-99b8-3bdabac4d2ed"/>
<containedObjects classId="e3687481-0a87-462c-a166-9f34594f9bba" objectId="c2f98eea-d716-482c-8b7d-b3fc30f88f53"/>
<containedObjects classId="9de14907-ec23-4a07-96f0-85521cb6b53b" objectId="011b4269-fe6f-4876-b48f-6894315ec46b"/>
<containedObjects classId="51f2d5d8-ea4d-4064-8892-82951750031e" objectId="f87a21ff-82a5-40f3-8c45-0b72448175de"/>
<containedObjects classId="e68182ea-4237-4383-967f-90c1e3370bc7" objectId="4206d029-9520-4b4e-a4ce-24b61c5f219b"/>
<containedObjects classId="fb282519-d103-4dd3-bc12-cb271d631dfc" objectId="305fd434-af42-4e89-ad3d-c2c8d426eeba"/>
<configurationExtensionCompatibilityMode>8.3.19</configurationExtensionCompatibilityMode>
<defaultRunMode>ManagedApplication</defaultRunMode>
<usePurposes>PersonalComputer</usePurposes>
<usedMobileApplicationFunctionalities>
<functionality>
<use>true</use>
</functionality>
<functionality>
<functionality>OSBackup</functionality>
<use>true</use>
</functionality>
</usedMobileApplicationFunctionalities>
<defaultLanguage>Language.English</defaultLanguage>
<dataLockControlMode>Managed</dataLockControlMode>
<objectAutonumerationMode>NotAutoFree</objectAutonumerationMode>
<modalityUseMode>DontUse</modalityUseMode>
<synchronousPlatformExtensionAndAddInCallUseMode>DontUse</synchronousPlatformExtensionAndAddInCallUseMode>
<compatibilityMode>8.3.19</compatibilityMode>
<languages uuid="e486c146-37cf-4259-b763-c572f1a9343f">
<name>English</name>
<synonym>
<key>en</key>
<value>English</value>
</synonym>
<languageCode>en</languageCode>
</languages>
<roles>Role.TestRole1</roles>
<commonModules>CommonModule.RolesCommonModule</commonModules>
<commonModules>CommonModule.Users</commonModules>
</mdclass:Configuration>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<Rights xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://v8.1c.ru/8.2/roles" xsi:type="Rights">
<setForNewObjects>false</setForNewObjects>
<setForAttributesByDefault>true</setForAttributesByDefault>
<independentRightsOfChildObjects>false</independentRightsOfChildObjects>
<object>
<name>Configuration.IsInRoleMethodRoleExist</name>
<right>
<name>SaveUserData</name>
<value>true</value>
</right>
<right>
<name>ThinClient</name>
<value>true</value>
</right>
<right>
<name>WebClient</name>
<value>true</value>
</right>
<right>
<name>MainWindowModeEmbeddedWorkplace</name>
<value>true</value>
</right>
<right>
<name>MainWindowModeKiosk</name>
<value>true</value>
</right>
<right>
<name>MainWindowModeNormal</name>
<value>true</value>
</right>
<right>
<name>MainWindowModeFullscreenWorkplace</name>
<value>true</value>
</right>
<right>
<name>MainWindowModeWorkplace</name>
<value>true</value>
</right>
<right>
<name>AnalyticsSystemClient</name>
<value>true</value>
</right>
</object>
</Rights>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Role xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="f34da7cf-73e2-4936-a972-c6f281dcf791">
<name>TestRole1</name>
<synonym>
<key>en</key>
<value>Test role1</value>
</synonym>
</mdclass:Role>