JanssenProject / jans

An open source enterprise digital identity platform for CIAM or workforce... Janssen is a distribution of standards-based, developer friendly, components that are engineered to work together in any cloud. #OAuth #OpenID #FIDO
https://docs.jans.io
Apache License 2.0
440 stars 73 forks source link

ProjectPasskeys: Refactor Assertion/Attestation to Jackson ObjectMapper #8907

Closed yackermann closed 2 weeks ago

yackermann commented 1 month ago

Currently all options/init requests, option/init responses, and assertion/attestation results are managed as Jackson JsonNode, which basically means that all options are managed by hand.

To address it, I propose factory approach with Jackson Object mapping:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class MyFactoryClass {
    // Example fields
    private String name;
    private int age;

    // Default constructor
    public MyFactoryClass() {
    }

    // Constructor using fields
    public MyFactoryClass(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and setters
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    // Method to convert JsonNode to MyFactoryClass instance
    public static MyFactoryClass fromJsonNode(JsonNode jsonNode) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        // Convert JsonNode to MyFactoryClass
        return objectMapper.treeToValue(jsonNode, MyFactoryClass.class);
    }

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"name\":\"John Doe\",\"age\":30}";

        try {
            // Parse JSON string to JsonNode
            JsonNode jsonNode = objectMapper.readTree(json);
            // Convert JsonNode to MyFactoryClass instance
            MyFactoryClass myFactoryClass = MyFactoryClass.fromJsonNode(jsonNode);
            System.out.println("Name: " + myFactoryClass.getName() + ", Age: " + myFactoryClass.getAge());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

https://stackoverflow.com/questions/6311921/best-way-to-use-jackson-jsonnodefactory

This would simplify management of the requests, and let Jans to have class method for validating requests/responses.

yackermann commented 1 month ago

Ref #5142

duttarnab commented 1 month ago

I found the following advantages in having class models (pojos). I am making changes keeping above points in mind.

  1. Readability - You will not really know the structure of a complex json. writing a simple get will require one to know the structure of the json.

  2. Offers Type Checks - We could easily assign a Cat to a Dog and not even know about it till runtime.

  3. Feels more object-oriented with Composition & encapsulation - It's easy to understand the designer's perspective with a POJO. A Car which IS-A Vehicle that HAS-A Wheel.

  4. You could choose what you wanna deserialize and keep only that in memory - When deserializing the object that we have just received over the network, with a JSON Object, there is no way to choose what has to be deserialized and stored into memory. If you have an object of 1 MB size where only 200 Bytes is your payload, we will end up holding the entire 1 MB object in memory if we don't use POJOs.

  5. Allows collection to be used and stream operations on them in a legible way - There is no native support for stream operations in a JsonNode. We will need to use a StreamStupport object which could be avoided.

  6. Allows cross framework referencing. With a few annotations, you can choose to map specific fields to a database client - When you use an ORM framework for you database, it's easy to annotate and map entities to the database schema.

  7. Naturally supports design patterns

  8. Minimalizing non-native dependencies - Why do you have to use a JsonNode or equivalent that does not come by itself in native Java? Especially if it has the above disadvantages.