Wednesday, November 2, 2022

.netCore Global Filter with injected services inside.

 problem:

when using global filter to authorize user with custom service function inside the IActionFilter

i have object reference Error for  for the service instance.

    public class GlobalActionFilter : IActionFilter

    {

        private readonly IUserAuthorizationService userAuthorizationService;


        public GlobalActionFilter(IUserAuthorizationService userAuthorizationService)

        {

            this.userAuthorizationService = userAuthorizationService;

        }

       

        public void OnActionExecuted(ActionExecutedContext context)

        {

        }

        public void OnActionExecuting(ActionExecutingContext context)

        {

            // our code before action executes

            try

            {

                string user = context.HttpContext.User?.Claims?.FirstOrDefault(i => i.Type == "name")?.Value;

                string tenantId = context.HttpContext.User?.Claims?.FirstOrDefault(i => i.Type == "tid")?.Value;

                tenantId ??= context.HttpContext.User?.Claims?.FirstOrDefault(i => i.Type == "http://schemas.microsoft.com/identity/claims/tenantid")?.Value;

                string subjectId = context.HttpContext.User.Claims?.FirstOrDefault(i => i.Type == "sub").Value;

                Audit.Core.IAuditScope auditScope = context.HttpContext.GetCurrentAuditScope();

                auditScope.SetCustomField("Username", user);

                auditScope.SetCustomField("TenantName", tenantId);

                var param = context.ActionArguments.SingleOrDefault(p => p.Key.ToLower()=="tenantid");

                context.ActionArguments.TryGetValue("TenantId", out object actionTenantId);

                if (actionTenantId != null)

                {

                    if(int.TryParse(tenantId, out int loggedInUserTenantId))

                    {

                        if (!userAuthorizationService.CheckTenantAdminPolicyForLoggedInUser(subjectId, loggedInUserTenantId, (int)actionTenantId))

                            context.Result = new UnauthorizedObjectResult("user is unauthorized");

                    }

                    

                }

            }

            catch (System.Exception)

            {

            }

        }

    }

Startup configuration for MyGlobal Custom filter.

 services.AddControllers(configure =>

            {

                AuditConfiguration.ConfigureAudit(services, Configuration);

                AuditConfiguration.AddAudit(configure);


                configure.Filters.Add(new GlobalActionFilter());

            });

---------------------------------------------------------------------------

solution:

implement new class inherits from IFilterFactory and inject service for my global action filter inside.

public class AuthorizationFilterFactory : IFilterFactory

    {

        public bool IsReusable => false;


        public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)

        {

            // manually find and inject necessary dependencies.

            var context = (IUserAuthorizationService)serviceProvider.GetService(typeof(IUserAuthorizationService));

            return new GlobalActionFilter(context);

        }

    }

}

then Edit startup configuration for as follow

  services.AddControllers(configure =>

            {

                AuditConfiguration.ConfigureAudit(services, Configuration);

                AuditConfiguration.AddAudit(configure);


                //configure.Filters.Add(new GlobalActionFilter());

                configure.Filters.Add(new AuthorizationFilterFactory());

            });


Tuesday, November 1, 2022

check sql server database for bulk data exist or not

 problem:

i have role with multiple policies and every policy have multiple permissions relates.

so i need to validate end user to insert new role with restriction to prevent repeate roles with the same policies and permissions.

solution:

create stored procedure for sql database to check if role (policies and related permissions) exists befor 

if exist the procedure will return the name for rule and application will show error message that the role is with the same permissions exists before you can use it.


1- create user defined type to pass to procedure which will be passed from application and checked by procedure.

Create Type RolePermissionType 

as Table (

policyid int,

TenantId int,

PermissionId int

)

------------------------------------------------------------------------------------------------------------------- 

2-create the procedure based on input with type RolePermissionType.

 

Create Procedure [dbo].[sp_Check_RoleExist](@Mypermission RolePermissionType readonly  , @RoleNameOut nvarchar(200) OUTPUT) as 

begin

declare @itemsCount int =(select count(*) from @Mypermission);

declare @QueryCount int ;

declare @RoleId int;

declare @RoleName nvarchar(200)

PRINT '@itemsCount = ' + CONVERT(varchar(10), @itemsCount)


DECLARE db_cursor CURSOR FOR 

SELECT roleId ,a.Name

FROM [PolicyServerDb].[dbo].[PermissionAssignments] ps

inner join [PolicyServerDb].dbo.Roles a on a.id  =ps.RoleId and a.PolicyId=32

group by RoleId ,Name

having count(roleId) =@itemsCount


OPEN db_cursor  

FETCH NEXT FROM db_cursor INTO @RoleId ,@RoleName


WHILE @@FETCH_STATUS = 0  

BEGIN

set @QueryCount =(

select count(*) from

(

     select  PolicyId,TenantId,PermissionId from [PolicyServerDb].[dbo].[PermissionAssignments]

where RoleId=@RoleId

  intersect select PolicyId,TenantId,PermissionId from @Mypermission

)as x )

if(@QueryCount = @itemsCount)

set @RoleNameOut = @RoleName

else

set @RoleNameOut=''


FETCH NEXT FROM db_cursor INTO @RoleId ,@RoleName

END 

CLOSE db_cursor  

DEALLOCATE db_cursor 

end

-------------------------------------------------------------------

3-C# function which returns rule name in case roleExists

   public string GetRoleNameByPermissionAssignments(PackageViewModel model)

        {

            string rolenameout = string.Empty;

            DataTable dt = new();

            dt.Clear();

            _ = dt.Columns.Add("policyid");

            _ = dt.Columns.Add("TenantId");

            _ = dt.Columns.Add("PermissionId");

            foreach (PolicyPermissions item in model.PolicyPermissions)

            {

                foreach (SimplePermission permission in item.permissions)

                {

                    _ = dt.Rows.Add(item.PolicyId, model.TenantId, permission.PermissionId);

                }

            }

            using (PolicyServerDbContext context = new())

            {

                SqlParameter Par1 = new("@Mypermission", dt)

                {

                    TypeName = "dbo.RolePermissionType",

                    Direction = ParameterDirection.Input

                };

                SqlParameter Par2 = new("@RoleNameOut", rolenameout)

                {

                    SqlDbType = SqlDbType.NVarChar,

                    Size = 200,

                    Direction = ParameterDirection.Output

                };

                _ = context.Database.ExecuteSqlRaw("exec dbo.sp_Check_RoleExist @Mypermission={0}, @RoleNameOut={1} out", Par1, Par2);

                if (Par2.Value != DBNull.Value)

                {

                    rolenameout = (string)Par2.Value;

                }

            }

            return rolenameout;

        }

if return empty string this meaning that role with passed permissions not exists.

DTO Passed To Function:

 public class PackageViewModel

    {

            public int RoleId { get; set; }

            public string RoleName { get; set; }

            public string PolicyId { get; set; }

            public string Tenant { get; set; }

            public string TenantId { get; set; }

            public string TenantProtected { get; set; }

            public string Description { get; set; }

            public bool AssignForChildTenant { get; set; }

            public int SelectedPolicyId { get; set; }

            public List<PolicyPermissions> PolicyPermissions { get; set; }

    }

 public class PolicyPermissions

    {

        public int PolicyId { get; set; }

        public int ParentId { get; set; }

        public string PolicyName { get; set; }

        public List<SimplePermission> permissions { get; set; }

    }

    public class SimplePermission {

        public int PermissionId { get; set; }

        public string PermissionName { get; set; }

    } 


Git Update Local Repositories.bat get remote branches to visual studio

  to update local repositories for Git Branches

create batch file in solution root folder then run the following command.

git remote update origin --prune

Tuesday, September 18, 2018

PLSQL CONCAT multiple rows in one string


     
       select CONCAT(REPLACE(listagg( ENTITY_NAME, chr(300)||'(') within group( order by NAME_TYPE_FLG DESC),',',' ')  ,')')AS X
 FROM  CISADM.CI_PER_NAME PN
            WHERE PN.PER_ID ='2252300000'
           AND  PN.NAME_TYPE_FLG IN(   'ALT' , 'PRIM')


output

another solution

SELECT wm_concat('('||ENTITY_NAME||')') 
 FROM
        (   SELECT PER_ID, PN.ENTITY_NAME
            FROM  CISADM.CI_PER_NAME PN
            WHERE PN.PER_ID ='2252300000'
           AND  PN.NAME_TYPE_FLG IN(   'ALT' , 'PRIM')
           ORDER BY PN.NAME_TYPE_FLG DESC
       )
       GROUP BY PER_ID ;


Tuesday, September 4, 2018

Oracle case when based on numeric check for varchar2 column and select based on range of integers

SELECT
 case
        when SUBSTR( CAST(PGEO.GEO_VAL AS NUMBER) , 1,3) <=199 then  'شرق المدينة'
        when  SUBSTR( CAST(PGEO.GEO_VAL AS NUMBER), 1,3) <=299 THEN   'شمال المدينة'
        when  SUBSTR( CAST(PGEO.GEO_VAL AS NUMBER), 1,3) <=399 then   'غرب المدينة'
        when  SUBSTR( CAST(PGEO.GEO_VAL AS NUMBER), 1,3) <= 499 then  'جنوب المدينة'
        when  SUBSTR( CAST(PGEO.GEO_VAL AS NUMBER), 1,3) <= 599 then 'وسط المدينة'
        else 'other'
     end AS GEO_VAL  ,COUNT(SA.SA_ID) AS ACCT_CNT
 FROM CISADM.CI_SA SA
INNER JOIN  CISADM.CI_PREM PREM ON PREM.PREM_ID = SA.CHAR_PREM_ID
INNER  JOIN CISADM.CI_PREM_GEO PGEO ON PGEO.PREM_ID = PREM.PREM_ID AND PGEO.GEO_TYPE_CD ='9405'--'9401'
 WHERE SA.CIS_DIVISION ='4501'
 AND SA.SA_STATUS_FLG  IN ('20')
 AND SA.SA_TYPE_CD IN ('184015','184012','184013')
 group by case
        when  SUBSTR( CAST(GEO_VAL AS NUMBER), 1,3) <=199 then  'شرق المدينة'
        when  SUBSTR( CAST(GEO_VAL AS NUMBER), 1,3)<= 299 then 'شمال المدينة'
        when  SUBSTR( CAST(GEO_VAL AS NUMBER), 1,3)<= 399 then   'غرب المدينة'
        when  SUBSTR( CAST(GEO_VAL AS NUMBER), 1,3) <= 499 then 'جنوب المدينة'
        when  SUBSTR( CAST(GEO_VAL AS NUMBER), 1,3) <= 599 then 'وسط المدينة'
        else 'other'
        end
        order by geo_val asc;
-------------------------------------------
result

 

Sunday, February 4, 2018

close bootstrap modal from iframe page when click on button

 

 Problem: i have button in Modal Page (using iframe to load another page inside)
i need to click on close button in child page to close the modal and refresh data in parent page
1- button code

     <asp:Button CssClass="btn btn-info m-bot15 closeStyle" runat="server" ID="btnReturnToMyTasks" Text="اغلاق الشاشة"  
         Width="150px" CausesValidation="False" meta:resourcekey="btnReturnToMyTasksResource1" OnClientClick='window.parent.$("#modal").modal("hide"); parent.refreshData(true);'/>  
------------------------------------
2- parent page script to refresh data when click on X button or when press on previous button from child page inside iframe

 
//////////////////////////////////////////////////////////////////////////////////// refresh data after modal close  
       $(window).bind("load", function () {  
         $(".closeStyle").click(function () {  
           refreshData(true);  
         });  
       });  
       function refreshData(args) {  
         try {  
           if (args) {  
             var masterTable = $find("<%= RadGrid1.ClientID %>").get_masterTableView();  
          masterTable.fireCommand("RebindGrid", "0");  
        }  
         else  
          return false;  
      }  
      catch (e) {  
        //do nothing  
      }  
       }  
       ////////////////////////////////////////////////////////////////////////////////////////////////////////////////


----------------------------------------------------------------------------------
Modal Html (inside master or parent page)

<!-- Modal -->  
     <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2" aria-hidden="true">  
       <div class="modal-dialog">  
         <div class="modal-content">  
           <div class="modal-header">  
             <!--onclick="alert('now in close'); window.location.reload();"-->  
             <button type="button" class="close closeStyle" data-dismiss="modal" aria-hidden="true" id="btnclose">&times;</button>  
             <h4 class="modal-title" id="myModalLabel2"></h4>  
           </div>  
           <div class="modal-body">  
             <iframe src="#" id="iframepopup" style="background-color: white;"></iframe>  
           </div>  
           <div class="modal-footer">  
             <button type="button" class="btn btn-primary closeStyle" data-dismiss="modal" id="Button1">اغلاق الشاشة</button>  
           </div>  
         </div>  
       </div>  
     </div>  
       
     -----------------------------------------------------------------------------------------
script to create modal height according to screen height

<script type="text/javascript">  
      $(document).ready(function () {  
        $('#modal').on('show.bs.modal', function () {  
          $('.modal-content').css('height', $(window).height() * 0.9);  
          $('.modal-body iframe').css('height', $(window).height() * 0.75);  
        });  
      });  
     </script>