Code Monkey home page Code Monkey logo

carmel-api's Introduction

carmel

bridge catalog application editor

This repo contains the Carmel backend application created in the form of an dotnet core / aspnet core / ef core application and the nodejs based utility that is being used to create the ef core database seed.

carmel-api's People

Watchers

 avatar  avatar

Forkers

thanood

carmel-api's Issues

Start developing Carmel with VS 2017

Introduction

As of 3/13/2017, the application in the dotnet folder is verified as correctly running with the Visual Studio 2017 Community edition

This document describes the details of running and further evolving this application

Carmel user interface issues

Catalog admin deals with components - shown below:

image

where each component has a number of samples:

image

Our current task is to provide the means to assign a list tags (strings) to each component and each sample for each component.

The second task is to provide the ability to add more samples for any existing component (I do not believe that it would make sense to add new components in a way that is different from what we have now).

Project Initialization

This is the approach I selected initially as it is the easiest to start with. The technology stack includes using MVC 6 in ASP.NET Core, ef core, Model Validation and TagHelpers

_This approach is based on Pluralsight courses "aspdotnetcore-efcore-bootstrap-angular-web-app" and "Implementing and Securing an API with ASP.NET Core"

carmel user interface design

Carmel being the application designed to facilitate the management of Catalog's samples (this includes KendoUI and Materialize Catalogs) requires pretty simple UI:

  1. Navigation UI needed to access the specific sample or the component where to add a new sample.
  2. Tag editor UI

Navigation UI

I propose to make it the same as the Catalog (reuse principle) - a design decision that will simplify the future merge of the Catalog with Carmel. Any location can be reached with three clicks

image
Image 1

Tag Editor

I propose to use the "central panel" (area where the sample is rendered) as the location for the Tag Editor. The Editor itself should be a composition of this very simple component:

image
Image 2

and a more elaborate form that is used to define other related metadata we would like to associate with each sample:

image
Image 3

Note this form will be properly redesigned to match our needs both in content and style.

feedback to Daniel and Jeroen's great adventure rebuilding carmel database

Item 1 - starting at ☝️ April 5, 2017 1:20 PM

This start immediately diverges from my path indicated here, and likely will result with more and more issues I will encounter in this feedback document. Rather than referring to too many dispersed hints why to use VS 2017 as the development tool (at least in the initial phase used to verify that Jeroen has the same bits as I do) I just wrote one common document explaining them.

This section addresses the Gitter discussion up to ☝️ April 5, 2017 1:30 PM

I would care to know why did @JeroenVinke decide to avoid this VS based approach, by the way.

Why VS 2017 - and not cli

Easy definition of matching libs

Only VS 2017 allowed me to ensure the need synchronization with Auth0 developers team - all of their original samples (hundreds of them) were developed with Visual Studio 2015 and before dot net core was available. I had the same history and spent almost a month trying to ensure that my existing code works with their samples. That horrible waste of time was ended when we all agreed to use VS 2017 - which brought the complete and compatible set of dotnet core libs. This document is the definition of the versions that should be used in Carmel-api.

"Standard" way of using local SQL database server

There are too many different versions of that database with too many ways of defining its location. Using VS solves this problem by

  1. Describing the path to the database in the VS project's integral document, which can be manipulated in the "standard way" using VS SQL Server Object Explorer:

image

  1. VS allows easy viewing and changing the data - if wne where needed

image

  1. Ensuring easy project portability between our team members

Data structures

Component

Any element from this collection

image

It is defined as

namespace Catalog.Models
{
    public class Component
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime DateCreated { get; set; }
        public string  UserName { get; set; }
        public ICollection<Sample> Samples { get; set; }
    }
}

Sample

image

Project Status

This information will be kept current to allow synchronization with other team members.


Stuff deleted

Today 2/16/2017 I am working on a prototype of a dotnet core application that can be deployed in Azure using app service approach. I am following the course Building Your First ASP.NET Core Web Application

My next step will be to use this deployment to Azure method to publish the first draft of the catalog admin application. None of the current content of this repository will survive in its current form. This initial form will have the initial UI rendered by aspnet, so that we can have the model for real Aurelia based front end.

Creating database

Note

This application should be compiled and executed using Visual Studio 2017 (I used the RC version) regardless of the established fact that it behaves the same when using Visual Studio 2015. Its other half (Carmel) cannot be built with Visual Studio 2015.


Introduction

This document explains the (quite convoluted, initially) process that uses the file https://aurelia-ui-toolkits.github.io/aurelia-kendoui-samples/samples.json as the definition of the collection of samples presented by the Aurelia KendoUI Bridge's Catalog application.

Configuration for Auth0 PaaS

These settings are defined in this quick start tutorial. As the initial definition of Carmel (a client in the Auth0 terminology) are that of a "Regular Web Application".

image

I will redefine the Carmel's name to be carmel-api and make it to be an aspnet-core-webapi compliant authentication. More specifically, this flow is demonstrated in the Authenticate with JWT (RS256) sample

The appsettings.json file is defined as

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Auth0": {
    "Domain": "aureliatools.auth0.com",
    "ClientId": "a03D2hkdqbYwilJiO7ZEg4NxPO2c3TDZ",
  }
}

proper use of Auth0 in aurelia applications

I am looking for the most aurelia "proper" way to use Auth0 - a problem that I am wrestling with for a really long time and only now reached the point where I can formulate the problem correctly (I hope 😄 )

Here is the reference to the "shortened" version of the standard aurelia navigation skeleton esnext application, which looks like this:

image

I want to require Auth0 based authentication in order to see the content of the GitHub Users menu, so I changed the view model of the app module to be

import {Redirect} from 'aurelia-router';

export class App {
  configureRouter(config, router) {

  var step = new AuthorizeStep;
  config.addAuthorizeStep(step)

    config.title = 'Aurelia-Auth0';
    config.map([
      { route: ['', 'welcome'], name: 'welcome',      moduleId: 'welcome',      nav: true, title: 'Welcome' },
      { route: 'users',         name: 'users',        moduleId: 'users',        nav: true, title: 'Github Users', settings: { auth: true }  },
      { route: 'login',         name: 'login',        moduleId: 'login',        title: 'Login' },
    ]);

    this.router = router;
  }
}


class AuthorizeStep {
  run(navigationInstruction, next) {
    if (navigationInstruction.getAllInstructions().some(i => i.config.settings.auth)) {
      var isLoggedIn = false;
      if (!isLoggedIn) {
        return next.cancel(new Redirect('login'));
      }
    }

    return next();
  }	
}

(Note that this is not yet added to https://github.com/aurelia-auth0/basic-templates/tree/master/skeleton-esnext repository).

The line var isLoggedIn = false; in the class AuthorizeStep is just a placeholder for the invocation of the authentication service offered by Auth0 - and this is where I would like to get the advice from someone who "speaks" better Aurelia than I do.

The following code is taken from the Auth0's current sample written for Aurelia users - the sample that made me accept the offer to take care of aurelia samples for Auth0 community, as it violates the Aurelia recommended approach that uses the router pipeline's authorization step.

import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-http-client';
import {Router} from 'aurelia-router';
import {tokenIsExpired} from './utils/tokenUtils';

@inject(HttpClient, Router)
export class App {
  message = 'Auth0 - Aurelia';
  lock = new Auth0Lock(AUTH0_CLIENT_ID, AUTH0_DOMAIN);
  isAuthenticated = false;
  
  constructor(http, router) {
    this.http = http;
    this.router = router;
    var self = this;
    
    this.router.configure(config => {
      config.map([
        {
          route: ['', 'public-route'],
          name: 'public',
          moduleId: './public-route'
        },
        {
          route: 'private-route',
          name: 'private',
          moduleId: './private-route'
        }
      ]);
    });
    
    this.lock.on("authenticated", (authResult) => {
      self.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error
          return;
        }

        localStorage.setItem('id_token', authResult.idToken);
        localStorage.setItem('profile', JSON.stringify(profile));
        self.isAuthenticated = true;
        self.lock.hide();
      });
    });

    if(tokenIsExpired())  {
      this.isAuthenticated = false;
    }
    else {
      this.isAuthenticated = true;
    }
  }
  
  login() {
    this.lock.show();   
  }
  
  logout() {
    localStorage.removeItem('profile');
    localStorage.removeItem('id_token');
    this.isAuthenticated = false;   
    this.decodedJwt = null;
  }
  
  getDecodedJwt() {
    let jwt = localStorage.getItem('id_token');
    if(jwt) {
      this.decodedJwt = JSON.stringify(jwt_decode(jwt), null, 2);
    }
    else {
      this.decodedJwt = "No JWT Saved";
    }
  }
}

Open issues

Since Auth0 provides full support for its services via Auth0 Admin Dashboard, the application using these services has to comply with

  1. Define callback URLs
    After the user authenticates we will only call back to any of these URLs. You can specify multiple valid URLs by comma-separating them (typically to handle different environments like QA or testing). You can use the star symbol as a wildcard for subdomains ('*.google.com'). Make sure to specify the protocol, http:// or https://, otherwise the callback may fail in some cases.

  2. Define callback URLs
    A set of URLs that are valid to redirect to after logout from Auth0. After a user logs out from Auth0 you can redirect them with the returnTo query parameter. The URL that you use in returnTo must be listed here. You can specify multiple valid URLs by comma-separating them. You can use the star symbol as a wildcard for subdomains ('*.google.com'). Notice that querystrings and hash information are not taking into account when validating these URLs. Read more about this at https://auth0.com/docs/logout

  3. Define allowed origins
    Allowed Origins are URLs that will be allowed to make requests from JavaScript to Auth0 API (typically used with CORS). By default, all your callback URLs will be allowed. This field allows you to enter other origins if you need to. You can specify multiple valid URLs by comma-separating them or one by line, and also use wildcards at the subdomain level (e.g.: https://*.contoso.com). Notice that querystrings and hash information are not taking into account when validating these URLs.

testing carmel-api with postman

Steps:

1 Using Visual Studio 2017 open this solution. Observe that the application is listening at port 8000:

image

2 Run that solution watching VS 2017 output panel. The application will start the browser and you should see the image below (the UI on this instance is prevented from causing any actions as these actions have to be invoked from carmel-fe)

image

3 Leave this app running and start postman. Set the url to http://localhost:8000/api/components** ensuring that you would be issues the http **get` command once you push on the Send button. However, before pushing on that button, set the breakpoint on this line - and then push on the Send button in postman.

image

You should see this same data in postman as

image

highlights of the carmel api entity framework core usage

carmel-api database is created using the "code-first" approach using classes in models folder as definition of entities.

The database is defined in the config.json file as the local instance of MSSQLLocalDB. This choice supports easy deployment to the production instance in the cloud. I tried to do this using Azure and we will likely have to do it in EWS/ECS for "business reasons" 😄 .

While the process of database creation appears to use the concept of migrations, for practical reasons I decided not to go beyond the first step in this process. In other words, when the carmel database has to be updated, it should repeat the whole database creation process, starting with updating the classes in the models folder. This allows the database maintenance with very minimal knowledge of "real" database administration.

carmel uses the standard repository pattern approach (note that this referenced article is a bit behind as it uses Visual Studio 2015). This further uses ef core context - as implemented in CatalogContext class. Note that this class defines the database as well as I had some difficulties using the previously mentioned config.json approach.

more on building carmel-api database

Based on today's discussion with @Thanood and @JeroenVinke I realized that there still are a few things that need explanation (to an acute observer, that is).

My approach to the solution of the problem of how to continue evolving carmel-api is incomplete as I focused too much on how to define the data needed to seed the database and have not clearly pointed out how to create the database structure.

  1. I used the ASP.NET Core - New Database as the guidance to create the database structure using the classes Component.cs, Sample.cs, ComponentTag.cs and SampleTag.cs in the models folder. **This action resulted with the creation of the Migrations folder.

  2. I used the **samples.json as the definition of the data used to seed the database (via the manual process described before, more than once)

  3. When making changes to the database, I only made the changes to the database seed (item 2 above), meaning that the content of the Migrations folder was constant so far.

Now, since we need to change the database structure in order to implement the two steps workflow designed to allow us the control over user edits, @JeroenVinke should decide whether he wants to use existing initial migration and build on top of that - or to delete the migrations folder and delete the database itself, basically starting from step 1 above.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.