FtpServer icon indicating copy to clipboard operation
FtpServer copied to clipboard

How to create readonly users?

Open TheTrigger opened this issue 5 years ago • 6 comments

How could I make a user be read-only on the filesystem? Working on aspnetcore 3.1

I have te code from the example:

/// <summary>
/// Custom membership provider
/// </summary>
public class CustomMembershipProvider : IMembershipProvider
{
    /// <inheritdoc />
    public Task<MemberValidationResult> ValidateUserAsync(string username, string password)
    {
        if (username != "tester" || password != "testing")
        {
            return Task.FromResult(new MemberValidationResult(MemberValidationStatus.InvalidLogin));
        }
            
        var user = new ClaimsPrincipal(
            new ClaimsIdentity(
                new[]
                {
                    new Claim(ClaimsIdentity.DefaultNameClaimType, username),
                    new Claim(ClaimsIdentity.DefaultRoleClaimType, username),
                    new Claim(ClaimsIdentity.DefaultRoleClaimType, "user"),
                },
                "custom"));

        return Task.FromResult(
            new MemberValidationResult(
                MemberValidationStatus.AuthenticatedUser,
                user));
    }
}
public static class FtpExtension
{
    public static void UseFtpServer(this IServiceCollection services)
    {
        services.AddFtpServer(builder => builder
            .UseDotNetFileSystem() // Use the .NET file system functionality
        );

        services.Configure<FtpServerOptions>(opt => opt.ServerAddress = "*");
        services.Configure<DotNetFileSystemOptions>(opt => opt.RootPath = Path.Combine("FtpServer"));
        services.AddHostedService<HostedFtpService>();

        services.AddSingleton<IMembershipProvider, CustomMembershipProvider>();
    }
}

thanks

TheTrigger avatar Jun 17 '20 09:06 TheTrigger

What I did is the following:

Added this to ValidateUserAsync claimList.AddRange(user.Roles.Select(x => new Claim(ClaimTypes.Role, x.ToString())).ToList());

And then added Custom Command Handler with this at the start:

        if (!this.Data.FtpUser.Claims.Any(x => x.Value == User.Roles.role_one.ToString().ToLower()) &&
           !this.Data.FtpUser.Claims.Any(x => x.Value == User.Roles.role_two.ToString().ToLower())
       )
        {
            throw new Exception("Not Allowed...");
        }

mo3head avatar Jun 23 '20 14:06 mo3head

Sorry, I don't mean how to authorize a user, but how to setup witch commands that user could call. I would like to have two users, one read-write, and another read-only, any ideas? ty

TheTrigger avatar Jun 23 '20 14:06 TheTrigger

That is exactly what I explained. Add specific role and check for it in a custom Controller ( i.e. CustomSTORController for disallowing write permission ).

mo3head avatar Jun 23 '20 14:06 mo3head

Sorry, I don't get it, I should be able to do this from CustomMembershipProvider so set the rights claims for MemberValidationResult...(?) I'm lost

TheTrigger avatar Jun 23 '20 14:06 TheTrigger

Same issue

Jinngoo avatar Nov 30 '20 08:11 Jinngoo

You can override the commands you want to control by creating and registering your own. Your commands take precedence. The samples show how to do this command registration.

In my case, i'm checking roles to create folders:

[FtpCommandHandler("MKD")]
public class MkdCommandHandler : FtpCommandHandler
{
    public override Task<IFtpResponse> Process(FtpCommand command, CancellationToken cancellationToken)
    {
        var user = CommandContext.FtpContext.Connection.Features.Get<IAuthorizationInformationFeature>().FtpUser;
        var roles = Startup.Settings.Roles;

        foreach (var claim in user.Claims)
        {
            var role = roles.FirstOrDefault(r => r.Name == claim.Value);
            if(role?.CanCreateFolder == true)
            {
                FubarDev.FtpServer.CommandHandlers.MkdCommandHandler mkdCommandHandler = new()
                {
                    CommandContext = this.CommandContext
                };

                return mkdCommandHandler.Process(command, cancellationToken);
            }
        }
        
        return Task.FromResult<IFtpResponse>(new FtpResponse(502, $"Not allowed!"));
    }
}

MarcoParreira avatar Mar 29 '23 17:03 MarcoParreira