Ionic 2 App Integration with Auth0 and Firebase

Problem Statement: Ionic 2 App authenticates using Auth0 and then using Auth0 token to firebase API as backend without using firebase authentication.

Solution: I have created base version of this project in GitHub. You can clone it from here.

https://github.com/giridharprakash/ionic2-auth0-angularfire.git

1. Clone the project
2. npm install ionic cordova typescript -g
3. After cloning project, run npm install for all local packages to install.

Step 1:

I am using facebook authentication with Auth0, so first we need to create facebook app in developer console.

Once you got application Id and App Secret then add the following Auth0 callback url on successful authentication. Fore new Apps, you need to add facebook login by clicking on “Add product” and then go to “Settings” to add callback Url.

Step 2:

Create Firebase app in console.
Now we need to get Api key to integrate to Auth0. Click on seetings icon.

Now go to Service Accounts and then click “Generate Private Key” downloads JSON. we will use this information in Auth0 Configuration.

Next need to get firebase config, for this go to Overview-> Add to web. this configuration is used in appmodule.ts

Step 3:

Create Auth0 Account
Now go to social connection and select facebook. Enter application id,app secret, scope you need for your application.

Create new application with type “Native”. Change callback url if needed.

Now go to Addons tab and enable firebase. Fill information in settings from the json file got from firebase.

Now go to connections tab in your app, go and enable facebook. if you remember we enabled facebook in social connection and then we add facebook for each and every app we work.

Step 4:

Now we will go through some of the code.

src/auth0-variables.ts: You will set Auth0 App details in this file before you run the application.
src/app/app.module.ts: We will configure angular fire module with firebase configuration info as shown above.
src/services/auth.service.ts:
login() method shows Auth0 screen.
constructor() This has authentication callback where we get Auth0 token and then we can get firebase access token.

Asp.Net Web API 2 Customize Token Expiration

Problem Statement: We need our Web API  to issue bearer tokens with different expiration based on type of the client (Web, Mobile and Desktop).

Solution 1: Let the WEB API always issue token with same expiration for every client. this is straight forward implementation done in application startup.

AccessTokenExpireTimeSpan: you can set this property based on the security needs of your application.


OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(2),
                //TODO
                // In production mode set AllowInsecureHttp = false
                AllowInsecureHttp = true,
                AuthenticationMode = AuthenticationMode.Active,
                AuthenticationType = OAuthDefaults.AuthenticationType
            };

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);

Solution 2: Let the Web API issue token with different expiration times based on the client type. we would give longer expiration for desktop clients.

OAuthAuthorizationServerOptions:
Provider: we have custom implementation for the ApplicationOAuthProvider as shown in Solution 1. Now for each client id we can set different expiration.
AccessTokenExpireTimeSpan: You need to comment this in start up configuration as shown in solution becuase you are customizing it in provider class.

Note: I didn’t provide full implementation here.


public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        string clientId;
        string clientSecret;
        //This AuthModel is my custom model that will be passed in OwinContext
        var authModel = new AuthModel();

        if (context.TryGetFormCredentials(out clientId, out clientSecret))
        {
            if (clientId.Equals("appWeb", StringComparison.OrdinalIgnoreCase))
            {
                context.Options.AccessTokenExpireTimeSpan = TimeSpan.FromHours(2);

                context.OwinContext.Set("oauth:client", authModel);
                context.Validated(clientId);// please validate client credentials.
            }
            else if (clientId.Equals("mobile", StringComparison.OrdinalIgnoreCase))
            {
                context.Options.AccessTokenExpireTimeSpan = TimeSpan.FromDays(3);
                authModel.ClientSecret = clientSecret;

                context.OwinContext.Set("oauth:client", authModel);
                context.Validated(clientId); // please validate client credentials.
            }
            else
            {
                context.SetError("invalid_client", "Client credentials are invalid.");
                context.Rejected();
            }
        }
        else
        {
            context.SetError("invalid_client", "Client credentials are invalid.");
            context.Rejected();
        }

        return Task.FromResult(0);
    }
}

Happy Coding!

Parse IIS Logs with Log Parser.

Requirement: Need some statistical data from IIS logs

Log parser: This is from Lizard Labs and it’s not free tool. This is very powerful tool with amazing GUI. Log Parser From Lizard Labs

Log Parser(Command Line): This is from Microsoft and it’s free. Download

I have used this command line interface to process the log files into database. I can run multiple reports once the data is in database.

Steps:

  1. Copy all the logs into separate directory.
  2. Open command prompt and go to “C:\Program Files (x86)\Log Parser 2.2”.
  3. Run the this statement to process logs and insert data into Sql Server.

LogParser "SELECT * INTO tablename FROM D:\Logs\*" -i:W3C -o:SQL -server:servername -database:databasename -driver:"SQL Server" -username:sa -password:**** -createTable:ON

Hint: you can find examples by running this command “logparser -h examples”.

Thank You

Code signing .Net assemblies with comodo certificate in Visual Studio

Requirements: Recently i got a requirement to publish code outside of our company as installation. We don’t want our users to see untrusted publisher error while using aour application.

Certificate from Comodo: You need to follow these steps to get (*.pfx) to sign the assemblies.

  1. Use only Internet explorer or Firefox . Chrome is not currently supported by Comodo.
  2. Create account and request for code signing certificate.
  3. After successful submission, you will receive email from comodo within 2 business days.
  4. Remeber, you need to use same system and same browser to install the certificate sent by Comodo.
  5. Once you install certifcate, you can export the certifcate as (*.pfx) file and sent the same to development team. Please secure this file with strong password.

As a developer: Follow these steps to sign the assemblies

  1. If you are getting error “Cannot find the certificate and private key for decryption.”. please follow steps to install your certificate. Follow Steps
  2. If you get error while signing “Cannot import the following key file: companyname.pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: VS_KEY_xxxxxxx”. now you can install key value pair to container by using below command."C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\sn.exe" i codesign.pfx VS_KEY_5FC66E4E834CAD9C
  3. In Visual Studio project properties, you can choose signing tab and then select the pfx to sign. i dont have luck with this approach, so i followed next step
  4. In Visual Studio project properties -> Build Events -> Post Build Scripts
    "C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe" sign /f "C:\anyfolder\codesign.pfx" /p password /tr "http://timestamp.comodoca.com" "$(TargetDir)*.dll"
  5. Now all your project assemblies should be signed. you can open properties of an assembly to confirm whether digital signatures tab is visible.

Happy Coding!

Using Google Authentication in Windows Applications

Goal: We have windows application built using .Net and this application should be able to retrieve basic information about the user like name, email and his unique parameters like google id etc.

Google Libraries: Google has developed and maintaining libraries as nuget packages for Open Id authentication and services like Google Plus, Google Drive etc.

Note: you can search using “Google.Apis.{google service like plus, drive}”. I am currently using their “Google.Apis.Plus.v1” with version 1.14.0.550

Prerequisites:

  1. We need to create an application in Google developer console.
  2. Next create Project, Credentials (Client Id, Secret) and enable  necessary API permissions. I have enabled Google + Api

Note: For windows applications client secret is really not a secret, so we really no need to worry keep it in secret place.

Application Changes:

Step 1:

We have all the information need to authenticate our users by using GoogleWebAuthorizationBroker.

var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets() {ClientId = "your client id", ClientSecret = "your client secret" },
new[] {PlusService.Scope.PlusMe, PlusService.Scope.UserinfoProfile, PlusService.Scope.UserinfoEmail}, "me", CancellationToken.None);

Step 2:

After step 1, your application should open browser for user to authenticate and authorize your app to use requested scopes.  Now we use below code to create Person Resource.

Note: Since our app is designed to get currently logged in user, we need to query people resource with id as “me”.


// Create the service.
var service = new PlusService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Sample",
});
var peopleResource = service.People.Get("me");
var person = await peopleResource.ExecuteAsync();

Step 3:

Now person object has all the basic information like email, display name, profile url etc.

Happy Coding.

 

Angular ui-grid without using scope

I started using Angular ui-grid in my application. I could found only documentation with $scope usage.

ui-grid version: 3.1.1

Link to ui-grid selection docs

Reason: one of the main reason why i want to avoid scope, our Angular 2 migration will be lot easy.

Created sample project in Plunker: Sample Project

grid.controller.js
Explanation:
1. In this ui-grid version both cell navigation and grid row selection will not work together
2. You can pass null value for scope parameter. you can refer to event registration in controller code.

gridApi.selection.on.rowSelectionChanged(null, _self.onSelectRow);
var GridController = (function () {
    function GridController() {
        this.gridOptions = this.getGridOptions();
        this.gridOptions.data = [{name: "test1", gender: "male", company: "com1"},
        {name: "test2", gender: "male", company: "com2"},
        {name: "test3", gender: "female", company: "com3"}]
    }
    GridController.prototype.getGridOptions = function () {
        var _self = this;
        return {
            enableRowSelection: true,
            enableRowHeaderSelection: false,
            columnDefs: [
                { field: 'name' },
      { field: 'gender' },
      { field: 'company' }
  ],
            appScopeProvider: _self,
            multiSelect: false,
            modifierKeysToMultiSelect: false,
            noUnselect: true,
            enableFiltering: true,
            enableSorting: true,
            onRegisterApi: function (gridApi) {
                _self.gridApi = gridApi;
                gridApi.selection.on.rowSelectionChanged(null, _self.onSelectRow);
            }
        };
    };
    GridController.prototype.onSelectRow = function (selectedRow) {
        console.log(selectedRow);
    };
    return GridController;
}());

script.js

Note: This has code for modules and directives. Directive uses controller as syntax

// Code goes here
(function() {
  var appControllers = angular.module("app.Controllers", []);
  appControllers.controller("GridController", GridController);

  var appDirectives = angular.module("app.Directives", ["ui.grid", "ui.grid.selection", 'ui.grid.cellNav', 'ui.grid.pinning']);

  appDirectives.directive("demoGrid", function() {
    return ({
      restrict: 'E',
      templateUrl: "grid.html",
      controller: "GridController as gc",
    });
  });

  var app = angular.module("app", ["app.Controllers", "app.Directives"]);

})();

Happy Coding!

Parameters creation for grouped elements in Revit

This is one problem took more time to solve.

Requirement: Addin should create parameters on launch.
Problem: We didn’t face any issues unless there are doors inside groups in the Revit model.

Step 1: Creating parameter is straight forward implementation from Revit API.

try
{
var doc = UIApp.ActiveUIDocument.Document;

/*create a temporary file to store parameters then apply to model*/

string originalFile = UIApp.Application.SharedParametersFilename;
string tempFile = Path.GetTempFileName() + “.txt”;
using (File.Create(tempFile)) { }
UIApp.Application.SharedParametersFilename = tempFile;
ExternalDefinitionCreationOptions edCO = new ExternalDefinitionCreationOptions(parameterName, parameterType);
edCO.Visible = isVisible;
var definition = UIApp.Application.OpenSharedParameterFile().Groups.Create(groupName).Definitions.Create(edCO);

/*revert file back to original file*/

UIApp.Application.SharedParametersFilename = originalFile;
File.Delete(tempFile);

var newCategory = doc.Settings.Categories.get_Item(builtInCategory);
var newCategorySet = UIApp.Application.Create.NewCategorySet();
newCategorySet.Insert(newCategory);
Autodesk.Revit.DB.Binding binding = UIApp.Application.Create.NewInstanceBinding(newCategorySet);

doc.ParameterBindings.Insert(definition, binding, paramGroup);
}

Now Step 2, mark that parameter with vary by group instance flag

var doc = UIApplication.ActiveUIDocument.Document;

/*Here element could be door and the parameterName that you just created or want to change*/
var opdef = element.LookupParameter(parameterName).Definition as InternalDefinition;
if (opdef != null && !opdef.VariesAcrossGroups)
opdef.SetAllowVaryBetweenGroups(doc, true);

Now Step 3: Here is the final change need to be done.
we tried to create different parameters with different data types like integer and text.

Note: Revit allowed us to create only parameters with type Text. It didn’t allow any other data types.

So in Step 1, Always set the parameterType to ParameterType.Text.

AngularJS setup with TypeScript

Recently I started building web applications with Angular and TypeScript. I thought it will good one to create a seed project to myself.

This project is created using
MVC 6, TypeScript and AngularJS 1.5
npm managing packages and running tasks

gulp: for running tasks
Reason:Tasks are written in JavaScript, so it’s much more easy to debug incase of errors.

typings: Since tsd is deprecated, I have used to install typescript definition files. Most of the editors are capable of providing IntelliSense based on these definition files.

browserify: This helps bundle packaging modules written in CommonJS.
Reason: This is much more closer to server side development like NodeJS.

template cache: This creates angular module with all the html templates in project.

sass: compiles all scss files to css
Reason: I chose scss because syntax is much closer to css.

normalize.css: This resets default styling in all major browsers. this helps us getting consisting look across all browsers.

Project can be downloaded from: download from github

Run the following commands from root folder where are config files are present (WebApp folder).

npm install typescript gulp -g

npm install

typings install

Happy Coding!