Skip to content

Commit

Permalink
refact(auth): refactoring domains (#120)
Browse files Browse the repository at this point in the history
* fix: update links

* refact: removing error in i18n

* feat: update documentation

* refact: update create table of user

* fix: link

* refact: refactoring domains

* fix: create account and active account

* fix: activation

* fix: login

* feat: moving folders to project root

* fix: testing

* refact: removing frontend

* refact: add pkg in utils

* feat: update readme
  • Loading branch information
isaqueveras committed Jul 29, 2023
1 parent 2710f8e commit 50479e8
Show file tree
Hide file tree
Showing 222 changed files with 1,665 additions and 22,833 deletions.
54 changes: 13 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,35 @@
# PowerSSO
PowerSSO is a fundamental piece that authenticates and manages users with the possibility of integration between systems using a Rest API and gRPC
PowerSSO is a authenticator and user manager for systems (under construction)

[If you want to use a web interface, run the project.](https://github.com/isaqueveras/powersso-ui)

<p>
<img alt="Go report" src="https://goreportcard.com/badge/isaqueveras/power-sso">
<img alt="" src="https://github.com/isaqueveras/power-sso/actions/workflows/go.yml/badge.svg">
<img alt="Repository size" src="https://img.shields.io/github/languages/top/isaqueveras/power-sso">
<img alt="Lines of code" src="https://img.shields.io/tokei/lines/github/isaqueveras/power-sso">
<img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/isaqueveras">
<img alt="GitHub language count" src="https://img.shields.io/github/languages/count/isaqueveras/power-sso?color=%2304D361">
<img alt="GitHub top language" src="https://img.shields.io/github/repo-size/isaqueveras/power-sso">
<a href="https://github.com/isaqueveras/power-sso/commits/main">
<img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/isaqueveras/power-sso">
</a>
<a href="https://github.com/isaqueveras/power-sso/stargazers">
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/isaqueveras/power-sso">
<img alt="Go report" src="https://goreportcard.com/badge/isaqueveras/powersso">
<img alt="" src="https://github.com/isaqueveras/powersso/actions/workflows/go.yml/badge.svg">
<img alt="Repository size" src="https://img.shields.io/github/languages/top/isaqueveras/powersso">
<img alt="Lines of code" src="https://img.shields.io/tokei/lines/github/isaqueveras/powersso">
<a href="https://github.com/isaqueveras/powersso/commits/main">
<img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/isaqueveras/powersso">
</a>
</p>

## 馃洜 Technologies

Some tools being used in this project: [Golang][golang], [React][reactjs], [TypeScript][typescript]

## 馃殌 How to run the project

### 馃搶 Prerequisites

Before you begin, you will need to have the following tools installed on your machine:
[Git](https://git-scm.com), [Node.js][nodejs] and [Golang][golang].
馃搶 Before starting, you will need to have the [Golang][golang] language installed on your machine.

### 馃Л Running the application

```bash
# Clone this repository
$ git clone https://github.com/isaqueveras/power-sso
$ git clone https://github.com/isaqueveras/powersso

# Access the project folder in your terminal/cmd
$ cd power-sso
$ cd powersso

# Install the dependencies
$ go mod tidy

# Run postgres database
$ make local
$ make dev

# Run the migrations
$ make migrate-up
Expand All @@ -53,19 +39,9 @@ $ make swag

# Run the application in development mode
$ go run main.go

# Access the project folder in your terminal/cmd
$ cd ui

# Install the dependencies
$ npm install

# Run the application in development mode
$ npm run start
```

```bash
- The frontend will open on the port:3000 # access http://localhost:3000
- The backend will open on the port:5000 # access http://localhost:5000
- The mailcatcher will open on the port:1080 # access http://localhost:1080
- The documentation will open on the port:5000: # access http://localhost:5000/swagger/index.html
Expand All @@ -80,12 +56,8 @@ $ npm run start
If you have any questions, check this [GitHub Contributing Guide](https://github.com/firstcontributions/first-contributions)

## Contributors
<a href="https://github.com/isaqueveras/power-sso/graphs/contributors">
<img src="https://contributors-img.web.app/image?repo=isaqueveras/power-sso&max=100" alt="List of contributors to the powerSSO project"/>
<a href="https://github.com/isaqueveras/powersso/graphs/contributors">
<img src="https://contributors-img.web.app/image?repo=isaqueveras/powersso&max=100" alt="List of contributors to the powerSSO project"/>
</a>

[reactjs]: https://reactjs.org
[typescript]: https://www.typescriptlang.org/
[nodejs]: https://nodejs.org/
[vscode]: https://code.visualstudio.com/
[golang]: https://go.dev/
206 changes: 206 additions & 0 deletions application/auth/auth_business.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// Copyright (c) 2022 Isaque Veras
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.

package auth

import (
"context"

"github.com/google/uuid"
"github.com/isaqueveras/powersso/database/postgres"
domain "github.com/isaqueveras/powersso/domain/auth"
infra "github.com/isaqueveras/powersso/infrastructure/persistencie/auth"
"github.com/isaqueveras/powersso/mailer"
"github.com/isaqueveras/powersso/oops"
"github.com/isaqueveras/powersso/tokens"
"github.com/isaqueveras/powersso/utils"
)

// CreateAccount is the business logic for the user register
func CreateAccount(ctx context.Context, in *domain.CreateAccount) error {
tx, err := postgres.NewTransaction(ctx, false)
if err != nil {
return oops.Err(err)
}
defer tx.Rollback()

if err = in.Prepare(); err != nil {
return oops.Err(err)
}

repoAuth := infra.NewAuthRepository(tx, mailer.Client())
repoUser := infra.NewUserRepository(tx)

if err = repoUser.Exist(in.Email); err != nil {
return oops.Err(err)
}

var userID *uuid.UUID
if userID, err = repoAuth.CreateAccount(in); err != nil {
return oops.Err(err)
}

var token *uuid.UUID
if token, err = repoAuth.CreateAccessToken(userID); err != nil {
return oops.Err(err)
}

if err = repoAuth.SendMailActivationAccount(in.Email, token); err != nil {
return oops.Err(err)
}

if err = tx.Commit(); err != nil {
return oops.Err(err)
}

return nil
}

// Activation is the business logic for the user activation
func Activation(ctx context.Context, token *uuid.UUID) (err error) {
var tx *postgres.Transaction
if tx, err = postgres.NewTransaction(ctx, false); err != nil {
return oops.Err(err)
}
defer tx.Rollback()

var (
repoAuth = infra.NewAuthRepository(tx, nil)
repoUser = infra.NewUserRepository(tx)
repoRole = infra.NewRoleRepository(tx)
)

activeToken := &domain.ActivateAccount{ID: token}
if err = repoAuth.GetActivateAccountToken(activeToken); err != nil {
return oops.Err(err)
}

if !activeToken.IsValid() {
return oops.Err(domain.ErrTokenIsNotValid())
}

user := domain.User{ID: activeToken.UserID}
if err = repoUser.Get(&user); err != nil {
return oops.Err(err)
}

if err = repoRole.Set(user.ID, utils.Pointer(domain.FlagEnabledAccount)); err != nil {
return oops.Err(err)
}

if err = repoAuth.MarkTokenAsUsed(activeToken.ID); err != nil {
return oops.Err(err)
}

if err = tx.Commit(); err != nil {
return oops.Err(err)
}

return nil
}

// Login is the business logic for the user login
func Login(ctx context.Context, in *domain.Login) (*domain.Session, error) {
tx, err := postgres.NewTransaction(ctx, false)
if err != nil {
return nil, oops.Err(err)
}
defer tx.Rollback()

var (
repoAuth = infra.NewAuthRepository(tx, nil)
repoUser = infra.NewUserRepository(tx)
repoSession = infra.NewSessionRepository(tx)
)

user := &domain.User{Email: in.Email}
if err = repoUser.Get(user); err != nil {
return nil, oops.Err(err)
}

if !user.HasFlag(domain.FlagEnabledAccount) {
return nil, oops.Err(domain.ErrNotHavePermissionLogin())
}

if !user.IsActive() {
return nil, oops.Err(domain.ErrUserNotExists())
}

if user.IsBlocked() {
return nil, oops.Err(domain.ErrUserBlockedTemporarily())
}

if err = in.ComparePasswords(user.Password, user.Key); err != nil {
if errAttempts := repoAuth.AddAttempts(user.ID); errAttempts != nil {
return nil, oops.Err(errAttempts)
}
if errAttempts := tx.Commit(); errAttempts != nil {
return nil, oops.Err(errAttempts)
}
return nil, oops.Err(err)
}

if user.OTPConfigured() {
if err = utils.ValidateToken(user.OTPToken, in.OTP); err != nil {
return nil, oops.Err(domain.ErrOTPTokenInvalid())
}
}

var sessionID *uuid.UUID
if sessionID, err = repoSession.Create(user.ID, in.ClientIP, in.UserAgent); err != nil {
return nil, oops.Err(err)
}

var token *string
if token, err = tokens.NewUserAuthToken(user, sessionID); err != nil {
return nil, oops.Err(err)
}

if err = tx.Commit(); err != nil {
return nil, oops.Err(err)
}

return &domain.Session{
SessionID: sessionID,
Level: user.Level,
UserID: user.ID,
Email: user.Email,
FirstName: user.FirstName,
LastName: user.LastName,
CreatedAt: user.CreatedAt,
Token: token,
RawData: make(map[string]any),
}, nil
}

// Logout is the business logic for the user logout
func Logout(ctx context.Context, sessionID *uuid.UUID) (err error) {
var tx *postgres.Transaction
if tx, err = postgres.NewTransaction(ctx, false); err != nil {
return oops.Err(err)
}
defer tx.Rollback()

if err = infra.NewSessionRepository(tx).Delete(sessionID); err != nil {
return oops.Err(err)
}

if err = tx.Commit(); err != nil {
return oops.Err(err)
}

return
}

// LoginSteps is the business logic needed to retrieve needed steps for log a user in
func LoginSteps(ctx context.Context, email *string) (res *domain.Steps, err error) {
var tx *postgres.Transaction
if tx, err = postgres.NewTransaction(ctx, true); err != nil {
return nil, oops.Err(err)
}
defer tx.Rollback()

repository := infra.NewAuthRepository(tx, nil)
return repository.LoginSteps(email)
}
Loading

0 comments on commit 50479e8

Please sign in to comment.