Sunday, May 29, 2016

Multiple non modal dialogs in Angular Material

Useful while panel not released (https://material.angularjs.org/HEAD/api/service/$mdPanel)

CSS to prevent modality:

.md-dialog-container {
    pointer-events: none;
}
md-dialog {
    pointer-events: all;
}

Dialog options:

{
/* Don't close this dialog when opening a new one */
    skipHide: true, 
/* Don't do the darkening of the whole screen */
    hasBackdrop: false 
}

References

Wednesday, May 25, 2016

CORS

Under certain request characteristics an additional request is automatically issued by the browser. This "preflight" request gathers CORS information form the server that is checked before making the real request.

References

Thursday, May 5, 2016

Custom authenication in QlikView Server (NTLM)

It's all about externalizing the user validation.

  • Some kind of username mapping (other system --> QlikView) is required.
  • Works on any Server edition (Small Business Edition and EE).
  • Document access is based on NTFS rights.
  • Every user must be given rights for every document. 
  • It should be easier and more flexible on Enterprise Edition by activating DMS.
  • Also easier with per session licensing (7x more expensive).
  • IIS required (it doesn't work with QVS).
Installation
  • Install IIS.
  • Install QlikView server with IIS-QV Tunneling.
  • Set anonymous authentication on the IIS administrator for QlikView and QvAjaxZfc.
  • On QMC System -> Setup -> QVW -> Authentication set:
    • Authentication: Always
    • Type: Ntlm
    • Login Address: Default login page
  • Edit C:\Program Files\QlikView\Server\QlikViewClients\QlikViewAjax\Authenticathe.aspx
Authenticate.aspx content

<%@ Import Namespace="QlikView.AccessPoint" %>
<%@ Import Namespace="QlikView.AccessPoint.HttpInterfaces" %>
<%@ Import Namespace="QvIISWebServer" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Collections.Generic"%>
<%@ Page Language="C#" AutoEventWireup="true" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e) {
        Response.Clear();
        Context context = this.GetContext();
        
        // Saving the Basic authentication header to a string ("Basic UserName:Password")
        string auth = Request.Headers["Authorization"];
        
        bool valid = false;
        string userName = "";            
        if (auth != null && auth.IndexOf("Basic ") == 0)
        {
            // Removing "Basic " from the string and decoding the username and password
            string unameColonPwd = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(auth.Substring(6)));
            int colonPos = unameColonPwd.IndexOf(':');
            if (colonPos >= 0)
            {
                // Splitting username:password into two seperate strings
                userName = unameColonPwd.Substring(0, colonPos);
                string pwd = unameColonPwd.Substring(colonPos + 1);
                
                // *** IMPLEMENT THIS FUNCTION WITH YOUR OWN USER VALIDATION 
                valid = checkCredentials(userName, pwd);
            }
        }            
        
        if(valid)
        {

            // *** IMPLEMENT THIS FUNCTION WITH YOUR OWN USER MAPPING
            userName = "DOMAIN\\" + mapUserName(userName);

            // *** IMPLEMENT THIS FUNCTION TO SET THE USER GROUPS
            // You can also return null on NTFS 
            List<string> groups = getUserGroups(userName);

            // Creating an user object with groups
            IUser user = new NamedUser(userName, groups, true);
            // Associate the IUser with the session cookie and either redirect or sent back a status code
            QlikView.AccessPoint.User.GenericAuthentication(context, user);
            //Stop now so we don't issue a new BASIC challenge                                
            
            /*
            YOU CAN USE THIS HELPER FUNCTION INSTEAD GenericAuthentication WHEN THE NT USER PASSWORD IS KNOWN
            IUser user = QlikView.AccessPoint.User.TryLogon("DOMAIN\\user", "pwd"); 
            */
        }
        else
        {
            Context.Response.StatusCode=401;
            Context.Response.AppendHeader("WWW-Authenticate","Basic realm=\"QlikView\"");
        }

        return;
    }
</script>

Internet references