Skip to content

x71c9/uranio-core

Repository files navigation

URANIO CORE

Uranio CORE is a Typescript repo that provides the Business Logic Layer (BLL) classes for an API service.

Uranio CORE can be extended to Uranio API for deploying a full webserice.

It can also be used for developing application that do not need a webservices, like native Apps.

It has built-in Access Control Layer (ACL) classes and Data Access Layer (DAL) classes.

For now it can interacts with MongoDB but more DB will be available in the future.

Atoms

In URANIO, a database record is called Atom.

For example there can be a Product Atom type.

The type of the object that represents the Product Atom will be Atom<'product'>.

The type Atom<T extends AtomName> accepts as generic the type AtomName.

The type AtomName is the union of all the Atom names.

The Atom names are auto generated by uranio-cli that reads the directory names inside src/atoms.

For example with this folder structure:

node_modules
src
`--atoms
   |--product
   |  `--index.ts
   `--customer
      `--index.ts

There will be generated an Atom with name product and an Atom with name customer.

type AtomName will be 'product' | 'customer'.

And Atom can be of type Atom<'product'> or Atom<'customer'>;

Atom definition

The Atom Atom<'product'> can be defined inside src/atoms/product/index.ts:

For example:

import uranio from 'uranio';

export default uranio.register.atom({
	properties: {
		title: {
			type: uranio.types.PropertyType.TEXT,
			label: 'Title'
		},
		price: {
			type: uranio.tyoes.PropertyType.FLOAT,
			label: 'Price'
		},
		// ...
	},
	// ...
});

It will make Atom<'product'> type:

const product:Atom<'product'> = {
	_id: '61d81a12f3e4ea6edbdcdd1e',
	_date: '2022-01-07T10:46:42.584Z',
	title: 'Product title',
	price: 119.99
};

Type Atom represents the type of the object stored in the database. Therefore it has, among the user defined properties, also the following ones:

  • _id
  • _date
  • _r (optional) - Reading permission [see section ACL]
  • _w (optional) - Writing permission [see section ACL]

AtomShape

An AtomShape has only the user defined properties. So it will be like so:

const product_shape:AtomShape<'product'> = {
	title: 'Product title',
	price: 119.99
};

This type is useful for insert a new Atom in the database.

Molecule

If an Atom has as parameter value another Atom is called Molecule.

Molecule<A,D> accept two generics. The first is the AtomName, the second is how deep goes the object definition.

For example if an Atom is defined like so:

// src/atoms/order/index.ts
import uranio from 'uranio';

export default uranio.register.atom({
	properties:{
		products: {
			type: uranio.types.PropertyType.ATOM_ARRAY,
			atom: 'product',
			label: 'Products'
		},
		customer: {
			type: uranio.types.PropertyType.ATOM,
			atom: 'customer',
			label: 'Customer'
		},
	}
});

The type Molecule<'order', 1> will be:

const product:Molecule<'order', 1> = {
	_id: '61dec7150529224d13ea7994',
	_date: '2022-01-12T12:18:29.617Z',
	products: [
		{
			title: 'Trousers',
			price: 119.99
		},
		{
			title: 'Shirt',
			price: 9.99
		}
	],
	customer: {
		first_name: 'John',
		email: 'john@email.com',
		...
	}
};

Molecule<'order', 0> is exactly like Atom<'order'>:

const product:Molecule<'order', 0> = {
	_id: '61dec7150529224d13ea7994',
	_date: '2022-01-12T12:18:29.617Z',
	products: ['61dec7150529224d13ea7997', '61de9f518fb75c70ad33310a'],
	customer: '61dc3434a99090002c28cb4b'
};

BLL: Business Logic Layer

Uranio CORE provides BLL classes for Atoms.

import uranio from 'uranio';

const products_bll = uranio.bll.create('product');
const product = await products_bll.find_by_id('61dec7150529224d13ea7997');

BLL Methods

The BLL provides the following methods to each realtion:

  • find
  • find_by_id
  • find_one
  • count
  • insert_new
  • update_by_id
  • update_one
  • remove_by_id
  • remove_one
  • authorize
  • upload (available only for Atom media)
  • presigned (available only for Atom media)

Authentication

Uranio CORE provides a BLL for authentication:

const auth_bll = uranio.bll.auth.create('superuser');
const urn_response = await auth_bll.authenticate('email@email.com', '[PASSOWRD]');
if(urn_response.success){
	const token = urn_response.payload.token;
}

bll.auth.create accept only AuthAtom.

See AuthAtoms

The method authenticate returns a token that can be use for authorization.

const passport = auth_bll.get_passort(token);
const products_bll = uranio.bll.create('product', passport);
const products = await products_bll.find({});

AuthAtoms

AuthAtoms are Atoms that can authenticate. In order to define an AuthAtom, it must have the attribute authenticate equal to true in book.ts.

// src/atoms/customer/index.ts
import uranio from 'uranio';

export default uranio.register.atom({
	authenticate: true,
	properties:{
		// ...
	}
});

Type AuthName is the union of all the Atom names that can authenticate.

AuthAtoms must have the properties email, password and groups defined like so:

// src/atoms/customer/index.ts
import uranio from 'uranio';

export default uranio.register.atom({
	authenticate: true,
	properties:{
		email:{
			type: uranio.types.PropertyType.EMAIL,
			...
		},
		password:{
			type: uranio.types.PropertyType.ENCRYPTED,
			...
		},
		groups:{
			type: uranio.types.PropertyType.ATOM_ARRAY,
			...
		}
	}
});

When a new AuthAtom is created, it will be created also the Group for it, so that each AuthAtom has at least its own group.

Groups are necessary for passing the ACL (Access Control Layer).

See ACL Section

Required Atoms

Uranio CORE provides out of hte box the following Atoms

  • superuser
  • group
  • user
  • media

It is possible to initialize Uranio without them by opting them out in the config file uranio.toml In order to use the ACL] superuser and group must be imported.

Superuser

Superusers are user that bypass the ACL (Access Control Layer). They can interact with the DB without authentication.

Superuser are AuthAtom

User

Users are entities that can interact with the DB after they have been authenticated.

User are AuthAtom

Group

Each AuthAtom can have multiple groups. The ACL (Access Control Layer) uses groups to give permission to the user.

Media

The Media relation has an additional method upload for uploading files.

Uranio CORE can upload media to AWS S3.

More platform will be adedd - i.e. Google Cloud Storage, Local, ...

Access Control Layer

The Access Control Layer is an Access Layer that will check if it is possible to make the query and filters the results with only the accessible data.

The permission on each Relation can be UNIFORM or GRANULAR.

Default is UNIFORM.

UNIFORM permission will check on a Relation level.

GRANULAR permission will check on a Record level.

In order to the ACL to work, it needs User and Group Relations. Each request is made by an User. Each User has Groups.

Each Relation and each Record have two attributes _r and _w, respectively for reading and writing permission. The value of these attributes is a Group ID Array.

_r will narrow from Everybody

_w will widen from Nobody

_r == nullish -> Everybody can read

_w == nullish -> Nobody can write

Database

Uranio CORE creates 3 connections to 3 different databases:

  • main
  • log
  • trash

The main db is where all the realations are stored by default.

The log db is made for storing logs.

The trash db stores a copy of all deleted records.

Search

MongoDB

When using MongoDB each Atom's property can have a key named search. If the key search is set to true MongoDB will make a text index on that key.

See Mongo docs

When the method search is called on a BLL class, URANIO will create a query in this fashion:

{$or: [{atom_key1: {$regex: query, $options: 'i'}}, {atom_key2: {$regex: query, $options: 'i'}}, ...]}

This will make a regex search on all the Atom's properties with search equal to true.

Releases

No releases published

Packages

No packages published