Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

As a user, I want to have extended usage plan #64

Open
kislerdm opened this issue Apr 7, 2023 · 0 comments
Open

As a user, I want to have extended usage plan #64

kislerdm opened this issue Apr 7, 2023 · 0 comments
Assignees
Labels
backend Core logic infrastructure Deployment and infra including CI and automation webui WebUI frontend
Milestone

Comments

@kislerdm
Copy link
Owner

kislerdm commented Apr 7, 2023

Problem

All users have a single plan for now. Many users would want to extend the quota, or have case-tailored usage conditions.

Proposed Solution

Implement user's authentication and authorisation using JWT.

References:

End-to-end flow: webclient

sequenceDiagram
     User->>Webclient: Initiates diagram's generation
     Webclient-->>Browser Cookies: Look up JWT tokens

alt "Login/Sign-in flow", the refresh token not found
     Webclient->>User: Login page
alt User opts-in for login
     User->>Webclient: Enter email address 
     Webclient-->Webclient: Login page's state transition: "input secret"
     Webclient->>AuthService: Call "/auth/email"

else User wants to continue without authN
     Webclient-->Webclient: Generate user's "fingerprint"
     Webclient->>AuthService: Call "/auth/anonym"
end

     AuthService-->AuthService: Validate request

alt User exist
     AuthService-->>DB: Lookup the user and status
     alt email_verified==true && active==false
        AuthService->>Webclient: Reply: 401
        Webclient->>Webclient: Error popup
     end
else User does not exist
      AuthService-->>DB: Create user: email_verified is false, active is false
end
     AuthService-->AuthService: Generate JWT ID token and secret
     AuthService-->>Cache: Store secret
     AuthService-->>SMTP: Dispatch the secret
     AuthService->>Webclient: Response: user_id+secret expiration time
     SMTP->>User: Deliver email with the secret     
     User->>Webclient: Input secret
     Webclient-->Webclient: Validate secret's expiration
     Webclient->>AuthService: Call "/auth/confirm"
     AuthService-->>Cache: Lookup secret
     AuthService-->AuthService: Validate secret
     AuthService-->>DB: Update user: email_verified is true, active is true
     AuthService-->AuthService: Generate JWT: Access and Refresh tokens
     AuthService->>Webclient: Response: JWT tokens
     Webclient-->>Browser Cookies: Store JWT tokens

else Referesh token found
     Webclient->>AuthService: Call "/auth/refresh"
     AuthService-->AuthService: Validate token
     
     alt Token is invalid
       AuthService->>Webclient: Response: 401
       Webclient->>Webclient: Error popup, init the "login/sign-in flow"
    else Token is valid
       AuthService-->>DB: Lookup the user and status
      alt active==true
         AuthService-->AuthService: Generate JWT: Access tokens
         AuthService->>Webclient: Response: Send JWT tokens
         Webclient-->>Browser Cookies: Store JWT tokens
      else active==false
        AuthService->>Webclient: Response: 401
        Webclient->>Webclient: Error popup, init the "login/sign-in flow"          
       end
    end

end
Loading

Contract

/auth/signin/init

Request:

Method Schema
POST
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/email:request",
  "type": "object",
  "required": [
    "email"
  ],
  "additional_fields": false,
  "properties": {
    "email": {
      "title": "User's email",
      "type": "string",
      "pattern": "^[a-zA-Z0-9+_.-]+@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$"
    }
  }
}

Responses:

Status Schema Reason
200
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/email:response-200",
  "type": "object",
  "required": [
    "user_id",
    "exp"
  ],
  "additional_fields": false,
  "properties": {
    "user_id": {
      "title": "User ID",
      "type": "string",
      "format": "uuid"
    },
    "exp": {
      "title": "Timestamp when the secret expires",
      "type": "integer",
      "minimum": 0
    }
  }
}
Secret sent to user's email
400
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Faulty input
401
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
User is deactivated
422
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Faulty email, the secret cannot be sent
500
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Internal server error

/auth/anonym

Request:

Method Schema
POST
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/anonym:request",
  "type": "object",
  "required": [
    "fingerprint"
  ],
  "additional_fields": false,
  "properties": {
    "fingerprint": {
      "title": "User's fingerprint",
      "type": "string",
      "pattern": "^[a-f0-9]{40}$"
    }
  }
}

Responses:

Status Schema Reason
200
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/anonym:response-200",
  "type": "object",
  "required": [
    "token_refresh",
    "token_access"
  ],
  "additional_fields": false,
  "properties": {
    "token_refresh": {
      "title": "JWT refresh token",
      "type": "object",
      "pattern": "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"
    },
    "token_access": {
      "title": "JWT access token",
      "type": "object",
      "pattern": "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"
    }
  }
}
OK
400
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Faulty input
500
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Internal server error

/auth/signin/confirm

Request:

Method Schema
POST
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/signin/confirm:request",
  "type": "object",
  "required": [
    "user_id",
    "secret"
  ],
  "additional_fields": false,
  "properties": {
    "user_id": {
      "title": "User ID",
      "type": "string",
      "format": "uuid"
    },
    "secret": {
      "title": "Authentication secret",
      "type": "string",
      "pattern": "^[0-9]{6}$"
    }
  }
}

Responses:

Status Schema Reason
200
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/confirm:response-200",
  "type": "object",
  "required": [
    "token_refresh",
    "token_access"
  ],
  "additional_fields": false,
  "properties": {
    "token_refresh": {
      "title": "JWT refresh token",
      "type": "string",
      "pattern": "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"
    },
    "token_access": {
      "title": "JWT access token",
      "type": "string",
      "pattern": "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"
    }
  }
}
OK
400
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Faulty input
401
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Unauthorized
500
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Internal server error

/auth/refresh

Request:

Method Schema
POST
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/refresh:request",
  "type": "object",
  "required": [
    "token_refresh"
  ],
  "additional_fields": false,
  "properties": {
    "user_id": {
      "title": "JWT refresh token",
      "type": "string",
      "format": "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"
    }
  }
}

Responses:

Status Schema Reason
200
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "/auth/refresh:response-200",
  "type": "object",
  "required": [
    "token_access"
  ],
  "additional_fields": false,
  "properties": {
    "token_access": {
      "title": "JWT access token",
      "type": "object",
      "pattern": "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"
    }
  }
}
OK
400
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Faulty input
401
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Unauthorized
500
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Error",
  "type": "object",
  "required": [
    "error"
  ],
  "additional_fields": false,
  "properties": {
    "error": {
      "title": "Error message",
      "type": "string"
    }
  }
}
Internal server error
@kislerdm kislerdm self-assigned this Apr 7, 2023
@kislerdm kislerdm added backend Core logic webui WebUI frontend infrastructure Deployment and infra including CI and automation labels Apr 7, 2023
@kislerdm kislerdm added this to the м0.0.7 milestone Apr 14, 2023
@kislerdm kislerdm moved this to In Progress in diagramastext Apr 14, 2023
@kislerdm kislerdm modified the milestones: м0.0.7, v0.0.7 Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Core logic infrastructure Deployment and infra including CI and automation webui WebUI frontend
Projects
Status: In Progress
Development

When branches are created from issues, their pull requests are automatically linked.

2 participants