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.
bridge catalog application editor
License: MIT License
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
Catalog admin deals with components - shown below:
where each component has a number of samples:
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).
This application lives here
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"
@Thanood's question and @adriatic's response result with the need to correct the code generator's GenerateSampleListSection
and rebuild the database.
Since each database instance is at the moment (before we deploy carmel-api to a cloud), this means that each of the team members would have to run git pull
command and rebuild carmel-api in Visual Studio.
Carmel being the application designed to facilitate the management of Catalog's samples (this includes KendoUI and Materialize Catalogs) requires pretty simple 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
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:
and a more elaborate form that is used to define other related metadata we would like to associate with each sample:
Note this form will be properly redesigned to match our needs both in content and style.
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.
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.
There are too many different versions of that database with too many ways of defining its location. Using VS solves this problem by
Any element from this collection
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; }
}
}
This information will be kept current to allow synchronization with other team members.
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.
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.
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.
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".
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",
}
}
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:
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";
}
}
}
Since Auth0 provides full support for its services via Auth0 Admin Dashboard, the application using these services has to comply with
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.
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
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.
1 Using Visual Studio 2017 open this solution. Observe that the application is listening at port 8000:
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)
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.
You should see this same data in postman as
I have a few years old Azure account that was created with my MSDN Visual Studio Premium account, which I used in this deployment test, based on https://docs.microsoft.com/en-us/aspnet/core/tutorials/publish-to-azure-webapp-using-vs
Here is the related video tutorial
Even more - https://docs.microsoft.com/en-us/azure/app-service-web/web-sites-deploy
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.
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.
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.
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)
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.