BEGIN TRANSACTION 
SET XACT_ABORT ON;
SET NOCOUNT ON;

USE [master]

IF EXISTS(SELECT 1 FROM master.dbo.syslogins WHERE name = 'SqlPrescAppTmpUsr')
BEGIN
  ALTER LOGIN SqlPrescAppTmpUsr WITH PASSWORD = N'exzIzPJ@2y9cErHbZh0@', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
  ALTER LOGIN SqlPrescAppTmpUsr ENABLE
END
ELSE
BEGIN
  CREATE LOGIN SqlPrescAppTmpUsr WITH PASSWORD = N'exzIzPJ@2y9cErHbZh0@', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
END	
GO


USE ArizonaREP;
GO



/*=============================================================================

  Script to create dbRolePrescriptionApp role.
  
  Role Name: dbRolePrescriptionApp
  TEMPLATE: Default
  
  EXAMPLE OF SECURABLES TO SET: 
 
  INSERT INTO #Securables
  VALUES
  ('DB','GRANT','VIEW DEFINITION','',''),
  ('SCHEMA','GRANT','SELECT,EXECUTE,INSERT,UPDATE,DELETE','','AP'),
  ('TABLE','GRANT','INSERT,UPDATE','Address','dbo'),
  ('SP','GRANT','EXECUTE','sp_bmc_GetNextID','dbo'),
  ('ROLE','GRANT','db_datareader','','')

  -----------------------------------------------
   
Generate date : 	2022-10-13 / up208700
	
=============================================================================*/

DECLARE @Command      NVARCHAR(MAX),
        @RoleName     VARCHAR(60),
        @Users        VARCHAR(255),
        @typeofobject VARCHAR(50),
        @grantordeny  VARCHAR(10),
        @rightsaction VARCHAR(255),
        @objectname   VARCHAR(255),
        @schemaid     VARCHAR(10),
        @sysTarget    VARCHAR(255),
        @sysType      VARCHAR(255);

SET @RoleName = 'dbRolePrescriptionApp';
SET @Command = N'';

/* TEMP TABLES */
CREATE TABLE #UsersOnRole (username VARCHAR(255));
CREATE TABLE #Securables (typeofobject VARCHAR(50),
                          grantordeny VARCHAR(10),
                          rightsaction VARCHAR(255),
                          objectname VARCHAR(255),
                          schemaid VARCHAR(10),
                          N2 BIT);

/* !!! LIST OF SECURABLES TO CHANGE !!! */

INSERT INTO #Securables
VALUES ('TABLE', 'GRANT', 'SELECT', 'Address', 'dbo', 0),
       ('TABLE', 'GRANT', 'SELECT', 'Address_key', 'dbo', 0),
       ('TABLE', 'GRANT', 'SELECT', 'Address_OU_Link', 'dbo', 0),
       ('TABLE', 'GRANT', 'SELECT', 'aps_authosization', 'dbo', 0),
       ('TABLE', 'GRANT', 'SELECT', 'Autorization_status_history', 'dbo', 0),
       ('TABLE', 'GRANT', 'SELECT', 'Telecom', 'dbo', 0);

/* GET ALL USERS ON THIS ROLE */
INSERT INTO #UsersOnRole
SELECT members.name
  FROM sys.database_role_members
  JOIN sys.database_principals roles
    ON database_role_members.role_principal_id   = roles.principal_id
  JOIN sys.database_principals members
    ON database_role_members.member_principal_id = members.principal_id
 WHERE roles.name = @RoleName;

/* CREATE ROLE */
SELECT @Command
    = N'
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = ''' + @RoleName
      + N''' AND type = ''R'')
BEGIN
  CREATE ROLE [' + @RoleName + N'] AUTHORIZATION [dbo]
  PRINT ''CREATE ROLE [' + @RoleName + N']''
END
';
EXEC sp_executesql @Command;

SET @Command = N'
DECLARE @SP_Name varchar(255)

';

/* SET ALL ROLE SECURABLES */
DECLARE SecurablesCurs CURSOR FOR
SELECT typeofobject,
       grantordeny,
       rightsaction,
       objectname,
       schemaid
  FROM #Securables
 WHERE N2 = 0;

OPEN SecurablesCurs;
FETCH NEXT FROM SecurablesCurs
 INTO @typeofobject,
      @grantordeny,
      @rightsaction,
      @objectname,
      @schemaid;
WHILE @@FETCH_STATUS = 0
BEGIN

    IF @typeofobject = 'DB'
    BEGIN
        IF EXISTS (   SELECT 1
                        FROM sys.fn_builtin_permissions('DATABASE')
                       WHERE permission_name = '' + @rightsaction + '')
        BEGIN
            SET @Command = @Command + @grantordeny + N' ' + @rightsaction + N' TO [' + @RoleName + N']
'           ;
        END;
    END;

    IF @typeofobject = 'SCHEMA'
    BEGIN
        SET @Command
            = @Command + N'
IF EXISTS (SELECT 1 FROM sys.schemas WHERE name = ''' + @schemaid
              + N''') 
BEGIN
  IF EXISTS(SELECT 1 FROM sys.fn_builtin_permissions(''SCHEMA'') WHERE permission_name = ''' + @rightsaction
              + N''')
  BEGIN
    '                  + @grantordeny + N' ' + @rightsaction + N' ON SCHEMA::' + @schemaid + N' TO [' + @RoleName
              + N']
  END
END

'       ;
    END;

    IF @typeofobject IN ( 'TABLE', 'SP', 'FUNCTIONS', 'VIEWS' )
    BEGIN

        IF @objectname LIKE '%[%]%'
        BEGIN

            IF @typeofobject = 'TABLE'
            BEGIN
                SET @sysTarget = 'sys.tables';
                SET @sysType = '';
            END;

            IF @typeofobject = 'SP'
            BEGIN
                SET @sysTarget = 'sys.procedures';
                SET @sysType = '';
            END;

            IF @typeofobject = 'FUNCTIONS'
            BEGIN
                SET @sysTarget = 'sys.objects';
                SET @sysType = ' and p.Type IN ( N''FN'', N''IF'', N''TF'', N''FS'', N''FT'' )';
            END;

            IF @typeofobject = 'VIEWS'
            BEGIN
                SET @sysTarget = 'sys.views';
                SET @sysType = '';
            END;

            SET @Command
                = @Command + N'
DECLARE SP_cursor CURSOR FOR 
SELECT p.name FROM '       + @sysTarget + N' p JOIN sys.schemas s ON s.schema_id = p.schema_id WHERE (p.name like '''
                  + @objectname + N''') and s.name = ''' + @schemaid + N'' + @sysType
                  + N'''

OPEN SP_cursor
FETCH NEXT FROM SP_cursor INTO @SP_Name
WHILE @@FETCH_STATUS = 0
BEGIN
  IF EXISTS(SELECT 1 FROM sys.fn_builtin_permissions(''OBJECT'') WHERE permission_name = ''' + @rightsaction
                  + N''')
  BEGIN
    EXEC('''               + @grantordeny + N' ' + @rightsaction + N' ON [' + @schemaid
                  + N'].['' + @SP_Name + ''] TO [' + @RoleName
                  + N']'')
  END
  FETCH NEXT FROM SP_cursor INTO @SP_Name
END

CLOSE SP_cursor
DEALLOCATE SP_cursor

'           ;

        END;
        ELSE
        BEGIN

            SET @Command
                = @Command
                  + N'
IF EXISTS(SELECT 1 FROM sys.objects o WITH (NOLOCK) JOIN sys.schemas s ON s.schema_id = o.schema_id WHERE o.name = '''
                  + @objectname + N''' AND o.type IN (N''U'',''P'',''V'',''FN'',''IF'',''TF'') AND s.name = '''
                  + @schemaid
                  + N''')
BEGIN
  IF EXISTS(SELECT 1 FROM sys.fn_builtin_permissions(''OBJECT'') WHERE permission_name = ''' + @rightsaction
                  + N''')
  BEGIN
    '                      + @grantordeny + N' ' + @rightsaction + N' ON [' + @schemaid + N'].[' + @objectname
                  + N'] TO [' + @RoleName + N']
  END
END

'           ;
        END;
    END;

    IF @typeofobject = 'ASSEMBLIES'
    BEGIN
        SET @Command
            = @Command + N'
IF EXISTS(SELECT 1 FROM sys.assemblies WHERE NAME = ''' + @objectname
              + N''')
BEGIN
  IF EXISTS(SELECT 1 FROM sys.fn_builtin_permissions(''ASSEMBLY'') WHERE permission_name = ''' + @rightsaction
              + N''')
  BEGIN
    '                  + @grantordeny + N' ' + @rightsaction + N'::[' + @objectname + N'] TO [' + @RoleName
              + N']
  END
END

'       ;
    END;

    IF @typeofobject = 'ROLE'
    BEGIN
        SET @Command
            = @Command
              + N'
IF NOT EXISTS (SELECT 1 FROM sys.database_role_members JOIN sys.database_principals roles ON database_role_members.role_principal_id = roles.principal_id JOIN sys.database_principals members ON database_role_members.member_principal_id = members.principal_id WHERE roles.name = '''
              + @rightsaction + N''' AND members.name = ''' + @RoleName + N''')
BEGIN
  EXEC sp_addrolemember N''' + @rightsaction + N''', N''' + @RoleName + N'''
END

'       ;
    END;

    FETCH NEXT FROM SecurablesCurs
     INTO @typeofobject,
          @grantordeny,
          @rightsaction,
          @objectname,
          @schemaid;
END;

CLOSE SecurablesCurs;
DEALLOCATE SecurablesCurs;

PRINT 'SET ALL SECURABLES ON ROLE [' + @RoleName + ']';
EXEC sp_executesql @Command;

/* ADD USER */
DECLARE UsersCurs CURSOR FOR SELECT username FROM #UsersOnRole;

OPEN UsersCurs;

FETCH NEXT FROM UsersCurs
 INTO @Users;
WHILE @@FETCH_STATUS = 0
BEGIN

    SELECT @Command = N'
EXEC sp_addrolemember N''' + @RoleName + N''', N''' + @Users + N'''
PRINT ''ADD USER [' + @Users + N'] ON ROLE [' + @RoleName + N']''
'   ;

    FETCH NEXT FROM UsersCurs
     INTO @Users;
END;

CLOSE UsersCurs;
DEALLOCATE UsersCurs;

EXEC sp_executesql @Command;


/*============================================================================= 
  Drop temp tables
=============================================================================*/
DROP TABLE #Securables;
DROP TABLE #UsersOnRole;

/*============================================================================= 
  Script to create / map all users
=============================================================================*/

DECLARE @username VARCHAR(255),
        @Database VARCHAR(255);

SET @username = '';
SET @Command = N'';
SET @Database = '';

CREATE TABLE #AllUsersAndRoles (databasename VARCHAR(255),
                                rolename VARCHAR(255),
                                username VARCHAR(255));

INSERT INTO #AllUsersAndRoles
VALUES ('ArizonaREP', 'dbRolePrescriptionApp', 'SqlAppPrescAppTmpUsrInt'),
       ('ArizonaREP', 'dbRolePrescriptionApp', 'SqlAppPrescAppTmpUsrProd'),
       ('ArizonaREP', 'dbRolePrescriptionApp', 'SqlAppPrescAppTmpUsrTest'),
       ('ArizonaREP', 'dbRolePrescriptionApp', 'SqlPrescAppTmpUsr');

DECLARE MapUsersAndRolesCurs CURSOR FOR
SELECT databasename,
       rolename,
       username
  FROM #AllUsersAndRoles AUAR
  JOIN master.sys.databases D
    ON D.name = AUAR.databasename;

OPEN MapUsersAndRolesCurs;
FETCH NEXT FROM MapUsersAndRolesCurs
 INTO @Database,
      @RoleName,
      @username;
WHILE @@FETCH_STATUS = 0
BEGIN

    SET @Command
        = N'USE ' + @Database + N'
IF EXISTS (SELECT 1 FROM master.dbo.syslogins WHERE name = ''' + @username
          + N''')
BEGIN
  IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = N''' + @RoleName
          + N''' AND [type] = ''R'')
  BEGIN
    IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = N''' + @username
          + N''')
    BEGIN
      ALTER USER [' + @username + N'] WITH LOGIN = [' + @username + N']
      EXEC sp_addrolemember N''' + @RoleName + N''', N''' + @username
          + N'''
    END
    ELSE
    BEGIN
      CREATE USER [' + @username + N'] FOR LOGIN [' + @username
          + N'] WITH DEFAULT_SCHEMA=[dbo]
      EXEC sp_addrolemember N''' + @RoleName + N''', N''' + @username + N'''
    END
  END
END
'   ;

    EXEC sp_executesql @Command;

    FETCH NEXT FROM MapUsersAndRolesCurs
     INTO @Database,
          @RoleName,
          @username;
END;

CLOSE MapUsersAndRolesCurs;
DEALLOCATE MapUsersAndRolesCurs;

DROP TABLE #AllUsersAndRoles;
GO

--ROLLBACK TRANSACTION 
COMMIT TRANSACTION
