2023

2023-08 August

2023-08-21 Monday

  • PlantUML and GraphViz (DOT)

    • PlantUML

      It is a tool (Java library/package) that helps one to create UML diagrams with ease.

      For the full details of it, one should look at https://plantuml.com/.

      The basic idea is that you write the diagram you need in plain text, and then using java + plantuml.jar (downloaded from the website above), generate a nice diagram.

      Your steps

      1. Setup java on your machine

      2. Download PlantUML.jar

      3. Create your text file for the diagram (see example here)

        @startuml
        
        title Your title
        center footer Your footer
        
        skinparam classFontName Georgia
        skinparam roundcorner 20
        skinparam defaultFontName Georgia
        skinparam dpi 160
        
        participant "Participant Fellow" as participant
        actor       Actor       as actor
        boundary    Boundary    as boundary
        control     Control     as control
        entity      Entity      as entity
        database    Database    as db
        collections Collections as colls
        queue       Queue       as q
        participant  -> actor : To actor
        participant  -> boundary : To boundary
        participant  -> control : To control
        participant  -> entity : To entity
        participant  -> db : To database
        participant  -> colls : To collections
        participant  -> q: To queue
        boundary -> actor : To actor
        control -> boundary : To boundary
        db -> control : To control
        actor -> entity : To entity
        entity -> db : To database
        q -> colls : To collections
        colls -> q: To queue
        
        @enduml
        
      4. Compile

        export JAVA_HOME=$(/usr/libexec/java_home) # set the JAVA_HOME variable
        java -jar path/to/plantuml.jar -verbose <inputfile>
        
      5. You will have the output as png in the folder.

    • DOT / Grapviz

      For this, you need to install graphviz on your system and should have the command dot available.

      Installation is straight forward in *nix machines. See https://graphviz.org/

      1. Install Graphviz, have Dot

      2. Create input file (example)

        digraph name  {
                Sample -> Diagram -> Workflow;
                Test -> Diagram;
                Sample -> Workflow
        }
        
      3. Run command dot -Tpng input.file > output.png

      4. You have the output ready.

2023-09 September

2023-09-04 Monday

  • Marshaling magic in Golang

    If you want to customise the json representation of a field in a golang struct, you can just add some custome JSON tag

    type OneStruct struct {
         PublicField `json"public_field"`
         AnotherField `json:"camelCasedInJSON"`
    }
    

    This won’t help you expose private fields. If you want to expose them, you need to override the MarshalJSON method of the struct. See the example below

    package main
    
    import (
            "encoding/json"
            "fmt"
    )
    
    type MyStruct struct {
            UpperCase string
            lowerCase string // NOTE: This field is not exported, and will not be in the json
            secret    string
    }
    
    // createStruct creates a struct with an exported and an unexported field.
    func createStruct() *MyStruct {
            return &MyStruct{
                    UpperCase: "UPPER",
                    lowerCase: "lower",
            }
    }
    
    // we implement the Marshaler interface for our struct.
    // This means that when we call json.Marshal on our struct, this
    // method will be called.
    func (s *MyStruct) MarshalJSON() ([]byte, error) {
            // we create a new "marshalable" struct with the fields we want to
            // export. We do not need to create a new type for this, we can
            // just use a struct literal.
    
            marshalable := struct {
                    UpperCase string `json:"upperCase"`
                    LowerCase string `json:"lower_case"`
            }{
                    // NOTE: The order of the keys is not guaranteed.
                    UpperCase: s.UpperCase,
                    LowerCase: s.lowerCase,
            }
    
            return json.Marshal(marshalable)
    }
    
    func main() {
    
            ourStruct := createStruct()
            json, err := json.Marshal(ourStruct)
            if err != nil {
                    fmt.Println(err.Error())
                    return
            }
    
            fmt.Println(string(json))
    }
    

    – sillyfellow @ [2023-09-04 Mon 11:17]

2023-12 December

2023-12-01 Friday

  • Refresh token (access token)

    • Do not use JWT (Just DON’T)
    • Always have a sessions table
      • Which belongs to the USER
        • i.e., sessions table has a user_id column
      • Have access_token and refresh_token
        • ideally as varchar(256), not text
        • do not allow them to grow
        • security shall be mostly based on rotation, not purely on length
      • Must have access_token_expires_at and refresh_token_expires at columns (both datetime, and keep them as UTC)
        • make sure to have these columns calculated during the creation of the session. Do not think of doing “time-math” for calculating expiry.
          • Because, you may login with one server, but the next server you have the auth checked might have a different time stamp/zone
      • access/refresh tokens shall be unique
    • From the above, it becomes possible to have multiple active sessions for one user.
      • If that is not desired, restrict that at code level, not at DB level
    • Generate random strings for access token and refresh token
      • keep them URLsafe (you’ll thank me when you have a mobile app)
      • Keep them about 256 char long
        • no longer
        • no shorter
    • Make access_expiry in a few minutes, and refresh_expiry in a few days
    • Standard auth is having authorisation header
      • Authorisation: Bearer <access-token>
    • Refresh token will require
      • Authorisation: Bearer <refresh-token>
    • Deal with Auth always in a middleware and keep the logged in user, or the session found by looking up the access_token (or refresh_token) in the sessions table
    • On refresh, delete the current session object, and create a new one with new
      • access_token, and new expiry in a few minutes
      • refresh_token, with new expiry in a few days
    • Disallow refresh if the refresh token is already expired
    • So, if a user logs in and is inactive for a few days, the refresh token expires, and they will have to login fresh again
    • But as long as the user does a “refresh” before the refresh-token is expired, they will have sessions alive always.