Permission defaults ignored in Orchard - permissions

I try to set permissions for my new module. Otherwise they seem to work, but the defaults are ignored, nothing is checked for role-permission pairs I've set in the code. My code (Permissions.cs) seems OK:
using System.Collections.Generic;
using Orchard.Environment.Extensions.Models;
using Orchard.Security.Permissions;
using Orchard.Environment.Extensions;
using My.Module.Utils;
namespace My.Module
{
public class Permissions : IPermissionProvider {
public static readonly Permission AccessMyModule = new Permission {
Description = Constants.AccessAddon, Name = "AccessMyModule"
};
public virtual Feature Feature { get; set; }
public IEnumerable<Permission> GetPermissions() {
return new[] {
AccessMyModule
};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = Constants.MyModuleAdministratorRole,
Permissions = new[] { AccessMyModule }
}
};
}
}
}
I double checked that all the constants stored in Constants and the references for them are valid. The code snippet here is simplified, in fact I have more permissions and more roles in my project, but I confirmed commenting out everything but one permission and one role doesn't fix the problem. The defaults for the other modules in the same solution work fine, though there's no bug reported by IntelliSense and everything else in the module seems to work. So where else could be the root of the problem?
EDIT: I followed #mdameer's comment and confirmed that GetDefaultStereotypes() really runs only after reinstall. However, an error occurred while enabling the module after reinstall, so the defaults were not loaded. I know that the supposed way is to check the role - permission name in the dashboard, but I would like to find another workaround, because
I would like to solve the error that occurred and not to risk it happenning on the production server as well, and I can't delete and reinstall this rather complex module several times just to debug this. It was likely caused by the reinstall process, nowhere in the permission initialization, but I can't know without running the code.
there are tens of roles affected, so relying on someone to click the permissions by hand each time means that there will likely be errors due to human factor.
The GetDefaultStereotypes() method is being called from class DefaultRoleUpdater in Orchard.Roles. It is called automatically from somewhere deep in the Orchard core, so simply mimicking the call and running it on startup isn't that easy. I also tried to mimic the whole function and placed it into my permissions class (or into a custom service), but now I got lost on how to run it. It is not static, but it either is part of or refers to my Permissions class, which doesn't allow for ordinary referencing by default (it has no proper constructor) and I don't want to mess it even more by changing the class to something it is not and shouldn't be.

Just set the default permissions you need in a migration instead of using GetDefaultStereotypes(). Here is a short example:
public class MyMigration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public MyMigration(Orchard.Roles.Services.IRoleService aRoleService)
{
mRoleService = aRoleService;
}
public int Create()
{
//mRoleService.CreateRole("MyRoleName");
//mRoleService.UpdateRole("MyRoleName", MyPermissions)
return 1;
}
// private
Orchard.Roles.Services.IRoleService aRoleService mRoleService;
}

Related

Unable to create a Role using RoleManager in Blazor Serverside

I had some code using the RoleManager that I had copied from an MVC project to create roles in a Blazor project.
It compiles okay but when I step through the code it gets to that line and then appears to throw and exception, as it doesn't ever go to the next line. I am unable to catch an exception though.
Since my code didn't work I found code on the web and it behaved the same, so I changed how it was injected and I got a different error, so I found a third way of doing it and that too gets to the line that tests to see if there is a role already existing and blows up.
Here is the latest attempt
[Inject]
IServiceProvider services {get;set;}
public async Task Initialize()
{
using (var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>())
{
string proRole = "Pro";
if (!await roleManager.RoleExistsAsync(proRole))
{
var temp = await roleManager.CreateAsync(new IdentityRole { Name = proRole });
}
}
}
And it blows up on the awaited if statement.
Here is the previous code that should work that doesn't.
string proRole = "Pro";
string proClientRole = "ProClient";
if (!await _roleManager.RoleExistsAsync(proRole))
{
var temp = await _roleManager.CreateAsync(new IdentityRole { Name = proRole });
}
which is inside of a method.
I also had it as #{code in the Razor file and after an hour of trying different things there I moved it to a base class because they have been more stable in the past.
It is not the database connection because that is well verified and also because UserManager is called in the same class and it work
I also tried this code (Blazor Role Management Add Role trough UI (Crud)) both suggestions.
This is one bad thing about Blazor for me is it is buggy I never know if it is my bad, or just something wrong with the latest greatest. But I am assuming it is my bad in this case.
Anyway any help would be much appreciated, I am way too many hours on this,
I copy/pasted the same code to the "/" page and it works there.
For some reason it wouldn't work in a component loaded into a component but the standard Role code works as expected in the "/" page.
Most likely I should have restarted my computer as it now works in the original location too.

Asp.net Boilerplate - Implement setting manager with database

I've been building an asp.net core website, using the asp.net boilerplate template. As of now, I've been storing all of the settings in the appsettings.json file. As the application gets bigger, I'm thinking I should start storing some settings via ABP's SettingProvider and ISettingStore.
My question is, does anyone have, or know of, a sample application that show's how to implement ISettingStore and storing the settings in the database?
The only post I could find so far is this, but the link hikalkan supplies is broken.
Thanks for any help,
Joe
ABP stores settings on memory with default values. When you insert a new setting value into database, then it reads from database and overrides the default value. So basically when database has no settings then it means all the settings are on default values. Setting values are stored in AbpSettings table.
To start using settings mechanism. Create your own SettingProvider inherited from SettingProvider. Initialize it in your module (eg:
ModuleZeroSampleProjectApplicationModule).
As SettingProvider is automatically registed to dependency injection; You can inject ISettingManager wherever you want.
public class MySettingProvider : SettingProvider
{
public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
{
return new[]
{
new SettingDefinition(
"SmtpServerAddress",
"127.0.0.1"
),
new SettingDefinition(
"PassiveUsersCanNotLogin",
"true",
scopes: SettingScopes.Application | SettingScopes.Tenant
),
new SettingDefinition(
"SiteColorPreference",
"red",
scopes: SettingScopes.User,
isVisibleToClients: true
)
};
}
}
In application services and controllers you don't need to inject ISettingManager
(because there's already property injected) and you can directly use SettingManager property. Forexample :
//Getting a boolean value (async call)
var value1 = await SettingManager.GetSettingValueAsync<bool>("PassiveUsersCanNotLogin");
And for the other classes (like Domain Services) can inject ISettingManager
public class UserEmailer : ITransientDependency
{
private readonly ISettingManager _settingManager;
public UserEmailer(ISettingManager settingManager)
{
_settingManager = settingManager;
}
[UnitOfWork]
public virtual async Task TestMethod()
{
var settingValue = _settingManager.GetSettingValueForUser("SmtpServerAddress", tenantAdmin.TenantId, tenantAdmin.Id);
}
}
Note: To modify a setting you can use these methods in SettingManager ChangeSettingForApplicationAsync, ChangeSettingForTenantAsync and ChangeSettingForUserAsync

How to enable module in Orchard migration?

I want to enable a specific module in a migration but the module is not enabled immediately.
The issue here seems to be the state of the module, it is set to Rising in table Orchard_Settings_ShellFeatureStateRecord. In this case I cannot enable the module manually in Admin anymore, I need to restart the web server after the migration has been executed to get the module to state Up.
The migration code looks like
public class Migration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public Migration(Orchard.Environment.Features.IFeatureManager aFeatureManager)
{
mFeatureManager = aFeatureManager;
}
...
public int UpdateFrom1()
{
System.Collections.Generic.Dictionary<string, Orchard.Environment.Extensions.Models.FeatureDescriptor> lFeatures =
mFeatureManager.GetAvailableFeatures().ToDictionary(m => m.Id, m => m);
if (lFeatures.ContainsKey("Orchard.Taxonomies"))
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"}, true);
...
}
// private
private readonly Orchard.Environment.Features.IFeatureManager mFeatureManager;
}
I also tried using IModuleManager, did not work. Then I tried enabling another simple feature like Orchard.Alias.UI, did not work either.
Is this intended behavior or what might be wrong in the code?
If your feature has a dependency on taxonomies, enabling it will also enable taxonomies. You don't need to do anything else. That is, unless the dependency is something new that you're adding with the new version. In that case, I'd probably display a warning asking the user to enable it, and I'd make the code resilient to taxonomies not being enabled (which is a good idea no matter what)
Change this line:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"},true);
to this one:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"});

Resolving constructor dependency on service used in NancyFX

I have the following bootstrap
public class NancyBootStrapper: DefaultNancyBootstrapper
{
protected override void ConfigureRequestContainer(TinyIoC.TinyIoCContainer container, NancyContext context)
{
base.ConfigureRequestContainer(container, context);
var ravenSession = container.Resolve< IRavenSessionProvider >().GetSession();
container.Register( ravenSession );
}
}
When my Nancy app tries to instantiate BlogService using the following constructor
public BlogService(IDocumentSession documentSession)
{
this.documentSession = documentSession;
}
the application blows up stating that it can't resolve document session, I have also tried the following within my test method (removing the constructor injection).
public void BuildCategories()
{
var container = TinyIoCContainer.Current;
documentSession = container.Resolve< IDocumentSession >();
documentSession.Store(new Category{Title = "test"});
documentSession.Store(new Category{Title = ".net"});
documentSession.SaveChanges();
}
This also blows up, pointing out that it can't resolve documentSession.
Now this is the first time I have used either NancyFX or TinyIoC so I could be doing something fundamentally wrong though I should mention that the documentSession does resolve within a Nancy module..
Can any one offer a fix or some suggestions?
When is the BlogService supposed to be instantiated? -My guess would be once for the application, in which case I believe you are registering the session in the wrong bootstrapper method, and should do it in ConfigureApplicationContainer.
I've been playing & digging into both NancyFx and the TinyIoC code bases and have figured out how to fix this issue... I don't like the fix... but hay it works :)
Basically, I am creating a RavenDB document session in the bootstrapper method configureRequestContainer as it is best practice to use the request as your unit of work scope.
Unfortunately anything that is auto wired by tinyIoC within configureApplicationContainer does not have any constructor injection performed using the child container being used by the Nancy request (this includes those that are marked as MultiInstance or as PerRequestSingleton.
To get around this, you need to re-register any components that depend on your per request components within the same child container.
As I said, I don't like the fix, but it is ultimately a fix :)

How to access methods from a class based wordpress plugin?

I have a plugin which registers a post type, taxonomy and handles some business logic.
I went ahead and made my perfectly working plugin OO based and now it only works some of the time.
Its set-up like the following:
class Fruit {
public function __construct() {
add_action('init', array(&$this, 'init'));
}
public function init() {
$this->the_apple();
}
public function the_apple() {
return print $apple = 'my apple';
}
}
$fruit = new Fruit();
Then in taxonomy.php, withing the loop the following works:
$fruit->the_apple();
But once I use get_template_part with loop.php, this no longer works
$fruit->the_apple();
I get the following notice:
Notice: Undefined variable the_apple();
My fix was to use:
global $fruit;
and now it works all the time, just fyi about globals they get a bad rep. and there's namespacing issues, along with dumping everything into globals vs. using a registry.
In production i would never use the name $fruit, instead i would call it,
global $skylar_fruit;