/exelor

Lightweight .net core api framework that includes jwt authentication with refresh token support, permission authorisation, auditing, logging, error handling, fluent validation, swagger, caching and rate limiting

Primary LanguageC#MIT LicenseMIT

Table Of Contents

Exelor

Exelor is a lightweight .net core api framework that includes jwt authentication with refresh token support, permission authorisation, auditing, logging, error handling, fluent validation, data shaping and rate limiting with Open API spec via swagger

Tech Stack

Features

Jwt and Refresh Tokens

Authentication in Exelor is done by issuing an access token with the users claims in it. You'll need to login to the application with a username and password and if successful, you'll get an access token that is valid for 15 minutes along with a refresh token that is valid for 2 days. You'll get a 401 response with a Token-Expired header when the Jwt token is no longer valid. You can ask for a new token from the refreshtoken endpoint.

Authorisation

By default all routes in Exelor needs to be authorised. If you don't want a specific route to authorised, say registering a new user, you need to add [AllowAnonymous] attribute to that route. Exelor supports permissions based authorisation, the access token that is issued contains the permissions claims which is used for authorisation.

You can authorise an action in 3 different ways

  • Attribute based authorisation: You can add HasPermission attribute to controllers/actions and provide a list of permission which has access to the controllers/actions
[HttpGet]
[HasPermission(Permissions.ReadUsers, Permissions.EditUsers)]
public async Task> Get(
	SieveModel sieveModel)
{
	return await _mediator.Send(new UserList.Query(sieveModel));
}
  • By checking if the user has a permission by calling IsAllowed
[HttpPut]
public async Task Edit(
	[FromBody] UpdateUser.Command command)
{
	if (!_currentUser.IsAllowed(Permissions.EditUsers))
		throw new HttpException(HttpStatusCode.Forbidden);
	return await _mediator.Send(command);
}
  • By validating a permission against the user (this throws an exception if the user doesn't have the permission in question)
[HttpDelete("{id}")]
public async Task Delete(
	int id)
{
	_currentUser.Authorize(Permissions.EditUsers);
	await _mediator.Send(new DeleteUser.Command(id));
}

Audit Logs

  • You can enable auditing of entities which will log changes done on entities to the database. This table will store who made the changes, the table on which the change was made, the key of the entity that was changed, old values before the change and new values after

Audit

Paging, Sorting and Filtering

  • You can use paging, sorting and filtering by using the Sieve model on Get endpoints which supports the following params (you can read more about Sieve here)
GET /GetPosts

?sorts=     LikeCount,CommentCount,-created         // sort by likes, then comments, then descendingly by date created 
&filters=   LikeCount>10, Title@=awesome title,     // filter to posts with more than 10 likes, and a title that contains the phrase "awesome title"
&page=      1                                       // get the first page...
&pageSize=  10                                      // ...which contains 10 posts

Data Shaping

  • You can request the fields that you are interested in and only those fields are returned in the response
GET /Roles

?fields=     Id, Name         // Only returns the Id and Name values
[
  {
    "Id": 1,
    "Name": "HR"
  },
  {
    "Id": 2,
    "Name": "Project Manager"
  }
]

Local Building

  • Install .NET Core SDK
  • Go to exelor folder and run dotnet restore and dotnet build
  • Add and run migrations   - Install ef tool by running dotnet tool install --global dotnet-ef   - Run dotnet ef migrations add Init and then dotnet ef database update
  • Run dotnet run to start the server at http://localhost:5000/
  • You can view the API reference at http://localhost:5000/swagger
  • Login using { "userName": "john", "password": "test" } for ReadUsers permission and { "userName": "jane", "password": "test" } for SuperUser permission

Run using docker

  • Add and run migrations
    • Install ef tool by running dotnet tool install --global dotnet-ef
    • Run dotnet ef migrations add "Init" --project Infrastructure --startup-project Web --output-dir Persistence\Migrations
  • Go to the root folder of the project and run docker-compose up
  • You can view the API reference at http://localhost:5000/swagger
  • Login using { "userName": "john", "password": "test" } for ReadUsers permission and { "userName": "jane", "password": "test" } for SuperUser permission

Config

ConnectionStrings

  • DefaultConnection: Server=exelor_db;Port=5432;Database=starter;Uid=su;Pwd=YourStrong!Passw0rd   - Postgres connection string, a default database called starter is created when you run migrations

JwtSettings

  • SecurityKey: A super secret long key to encrypt and decrypt the token
  • Issuer: Issuer
  • Audience: Audience   - The key, issuer and audience values to generate a jwt token

PasswordHasher

  • Key: Secret key to encrypt passwords   - The key to encrypt the passwords

AuditSettings

  • Enabled: true   - This is to enable or disable logging changes on the entities to Audits table

Serilog

  • MinimumLevel: "Default": "Information"
  • WriteTo: "Name": "Console"   - Configure serilog options. Check wiki for more options and modify appsettings.json

IpRateLimiting

  • IpWhitelist: [ "127.0.0.1", "::1/10", "192.168.0.0/24" ]
  • GeneralRules: ...   - Configure IpRateLimiting options. Localhost is whitelisted by default. Check wiki for more options and modify appsettings.json

Sieve

  • Sieve: "CaseSensitive": false, "DefaultPageSize": 50, "MaxPageSize": 100, "ThrowExceptions": true   - Default options for Sieve which is used for paging, sorting and filtering

How to Contribute

  1. Clone repo git clone https://github.com/simplyvinay/exelor.git
  2. Create a new branch: git checkout -b new_branch_name
  3. Make changes and test
  4. Submit Pull Request with description of changes

License

MIT