GithubHelp home page GithubHelp logo

cs122b-be1's Introduction

CS122B Backend 1 - The IDM Service

  1. POST: Register
  2. POST: Login
  3. POST: Refresh
  4. POST: Authenticate

Application Settings

Spring Boot can has a large number of settings that can be set with a file called application.yml.
This file is already provided for you and is placed here for reference.

application.yml
spring:
  application:
    name: IdmService
  datasource:
    url: jdbc:mysql://localhost:3306
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}

server:
  address: 0.0.0.0
  port: 8081
  error: # These settings are for debugging
    include-exception: true
    include-message: always

logging:
  file:
    name: ./IdmService.log

idm:
  key-file-name: ec-key.json
  access-token-expire: 30m
  refresh-token-expire: 12h
  max-refresh-token-life-time: 30d

Database

💾 idm.token_status
Column Name Type Attributes
id INT NOT NULL PRIMARY KEY
value VARCHAR(32) NOT NULL
💾 idm.user_status
Column Name Type Attributes
id INT NOT NULL PRIMARY KEY
value VARCHAR(32) NOT NULL
💾 idm.role
Column Name Type Attributes
id INT NOT NULL PRIMARY KEY
name VARCHAR(32) NOT NULL
description VARCHAR(128) NOT NULL
precedence INT NOT NULL
💾 idm.user
Column Name Type Attributes
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
email VARCHAR(32) NOT NULL UNIQUE
user_status_id INT NOT NULL
salt CHAR(8) NOT NULL
hashed_password CHAR(88) NOT NULL
Constraints
FOREIGN KEY (user_status_id) REFERENCES idm.user_status (id) ON UPDATE CASCADE ON DELETE RESTRICT
💾 idm.refresh_token
Column Name Type Attributes
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
token CHAR(36) NOT NULL UNIQUE
user_id INT NOT NULL
token_status_id INT NOT NULL
expire_time TIMESTAMP NOT NULL
max_life_time TIMESTAMP NOT NULL
Constraints
FOREIGN KEY (user_id) REFERENCES idm.user (id) ON UPDATE CASCADE ON DELETE CASCADE
FOREIGN KEY (token_status_id) REFERENCES idm.token_status (id) ON UPDATE CASCADE ON DELETE RESTRICT
💾 idm.user_role
Column Name Type Attributes
user_id INT NOT NULL PRIMARY KEY
role_id INT NOT NULL PRIMARY KEY
Constraints
PRIMARY KEY (user_id, role_id)
FOREIGN KEY (user_id) REFERENCES idm.user (id) ON UPDATE CASCADE ON DELETE CASCADE
FOREIGN KEY (role_id) REFERENCES idm.role (id) ON UPDATE CASCADE ON DELETE RESTRICT

Endpoints

Order of Validation

All ❗ 400: Bad Request Results must be checked first, and returned before any other action is made.
The order of the checks within ❗ 400: Bad Request is not tested as each Result is tested individually.

JsonInclude

In the case of non-successful results, where values are expected, the values should not be included, for example.

{
   "result": {
      "code": 32,
      "message": "Data contains invalid integers"
   },
   "value": null 
}

the value key should not be included:

{
   "result": {
      "code": 32,
      "message": "Data contains invalid integers"
   }
}

This is done by insuring that all null values are dropped by either:

  • Having your Model extend ResponseModel, or
  • Putting the @JsonInclude(JsonInclude.Include.NON_NULL) on your Model class

Result

All Result objects are avaible as static constants inside of the com.github.klefstad_teaching.cs122b.core.result.IDMResults class. These can be used rather than creating your own.

Register

Allows users to create login details given a valid email and password. Password must be hashed and salted with both values being stored in the idm.user table. The user is given no roles, as well as being assigned the user_status of ACTIVE, by default.

Path

POST /register

API

📥  Request
Model Example
email: String
password: char[]
{
    "email": "[email protected]",
    "password": ["p", "a", "s", "s", "w", "o", "r", "d"]
}
Key Required Description
emailYesMust be of the form [email]@[domain].[extension], be between [6-32] characters (inclusive), and contain only alphanumeric characters
passwordYesMust be between [10-20] alphanumeric characters (inclusive), contain at least one uppercase alpha, one lowercase alpha, and one numeric
📤  Response
Model Example
result: Result
    code: Integer
    message: String
{
    "result": {
        "code": 1010,
        "message": "User registered successfully"
    }
}
📦  Results
Status Code Message
✅ 200: Ok 1010 User registered successfully
❗ 409: Conflict 1011 User with this email already exists
❗ 400: Bad Request 1000 Password does not meet length requirements
❗ 400: Bad Request 1001 Password does not meet character requirement
❗ 400: Bad Request 1002 Email address has invalid format
❗ 400: Bad Request 1003 Email address has invalid length

Login

Allows users to login with credentials created in the /register endpoint. Returns both a accessToken and a refreshToken (with the refreshToken being stored in the idm.refresh_token table). Both tokens expiration dates are determined by the values supplied in the application.yml file.

AccessToken

An accessToken is built as follows:

  1. Build a JWTClaimsSet with the following claims:
    1. subject of the user's email
    2. expirationTime of the currentTime + accessTokenExpireTime found in the config
    3. issueTime the currentTime
    4. claim(JWTManager.CLAIM_ROLES) of the user's roles (user a list of the provided Role enum)
    5. claim(JWTManager.CLAIM_ID) of the user's id
  2. Build a JWSHeader with the JWTManager.JWS_ALGORITHM and the following:
    1. keyID of the ecKeyId found in your instance of JWTManager
      • found by calling manager.getEcKey().getKeyID()
    2. type of JWTManager.JWS_TYPE
  3. Build a SignedJWT with your created JWTClaimsSet and JWSHeader
  4. Sign by using calling signedJWT.sign(jwtManager.getSigner())
  5. Serialize by calling signedJWT.serialize()

RefreshToken

A refreshToken is created by calling UUID.randomUUID()

Path

POST /login

API

📥  Request
Model Example
email: String
password: char[]
{
    "email": "[email protected]",
    "password": ["p", "a", "s", "s", "w", "o", "r", "d"]
}
Key Required Description
emailYesMust be of the form [email]@[domain].[extension], be between [6-32] characters (inclusive), and contain only alphanumeric characters
passwordYesMust be between [10-20] alphanumeric characters (inclusive), contain at least one uppercase alpha, one lowercase alpha, and one numeric
📤  Response
Model Example
result: Result
    code: Integer
    message: String
accessToken: String (nullable)
refreshToken: String (nullable)
{
    "result": {
        "code": 1020,
        "message": "User logged in successfully"
    },
    "accessToken": "7f832c2e054ba732f7d4b7e26..."
    "refreshToken": "c46fc3c2-9791-44d6-a86e-2922ad655284"
}
📦  Results
Status Code Message
✅ 200: Ok 1020 User logged in successfully
❗ 401: Unauthorized 1021 User not found
❗ 403: Forbidden 1022 Passwords do not match
❗ 403: Forbidden 1023 User is locked
❗ 403: Forbidden 1024 User is banned
❗ 400: Bad Request 1000 Password does not meet length requirements
❗ 400: Bad Request 1001 Password does not meet character requirement
❗ 400: Bad Request 1002 Email address has invalid format
❗ 400: Bad Request 1003 Email address has invalid length

Refresh

Creates a new accessToken for the user given a valid and non-expired refreshToken that belongs to the user.

Flowchart

If the refreshToken passes basic validation ensure it follows this Flow Chart

Path

POST /refresh

API

📥  Request
Model Example
refreshToken: String
{
    "refreshToken": "c46fc3c2-9791-44d6-a86e-2922ad655284"
}
Key Required Description
refreshTokenYesMust be 36 characters in length and be a valid UUID formatted string
📤  Response
Model Example
result: Result
    code: Integer
    message: String
accessToken: String (nullable)
refreshToken: String (nullable)
{
    "result": {
        "code": 1030,
        "message": "AccessToken has been refreshed"
    },
    "accessToken": "7f832c2e054ba732f7d4b7e26..."
    "refreshToken": "c46fc3c2-9791-44d6-a86e-2922ad655284"
}
📦  Results
Status Code Message
✅ 200: Ok 1030 AccessToken has been refreshed
❗ 401: Unauthorized 1031 RefreshToken is expired
❗ 401: Unauthorized 1032 RefreshToken is revoked
❗ 401: Unauthorized 1033 RefreshToken not found
❗ 400: Bad Request 1032 RefreshToken has invalid length
❗ 400: Bad Request 1033 RefreshToken has invalid format

Authenticate

Authenticates a user's accessToken to ensure it is both valid and non-expired.

Verification

An accessToken can be verified in three steps:

  1. Verifying that the token is valid and issued by us by calling jwt.verify(jwtManager.getVerifier())
  2. Checking that the claims are consistent with what we expect by calling jwtManager.getJwtProcessor().process(jwt, null)
  3. Manually checking that the expireTime of the token has not passed.

Path

POST /authenticate

API

📥  Request
Model Example
accessToken: String
{
    "accessToken": "7f832c2e054ba732f7d4b7e26..."
}
Key Required Description
accessTokenYesMust be a valid JWT encoded string
📤  Response
Model Example
result: Result
    code: Integer
    message: String
{
    "result": {
        "code": 1040,
        "message": "AccessToken is valid"
    }
}
📦  Results
Status Code Message
✅ 200: Ok 1040 AccessToken is valid
❗ 401: Unauthorized 1041 AccessToken is expired
❗ 401: Unauthorized 1042 AccessToken is invalid

cs122b-be1's People

Contributors

alexvo7 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.