ballerina-lang icon indicating copy to clipboard operation
ballerina-lang copied to clipboard

Identify special field types in the ballerina records for UI generation

Open indikasampath2000 opened this issue 3 years ago • 1 comments

Description: ballerina/http ballerinax/mysql clients initialization may require some sensitive data such as clientId, clientSecret, password, path, etc. The type of these fields defined as strings.

public type RefreshTokenGrantConfig record {|
    string refreshUrl;
    string refreshToken;
    string clientId;
    string clientSecret;
public type ClientSecureSocket record {|
    boolean enable = true;
    crypto:TrustStore|string cert?;
    crypto:KeyStore|CertKey key?;
public type KeyStore record {|
    string path;
    string password;
|};

Describe your problem(s) When we want to generate UI controls for entering values for these fields, the possible control is a text box. Is it possible to introduce an annotation pattern to describe the data? For example, clientSecret should mask value, and the path should be a file upload, etc. @shafreenAnfar @daneshk thoughts?

Describe your solution(s)

Related Issues (optional):

Suggested Labels (optional):

Suggested Assignees (optional):

indikasampath2000 avatar Aug 02 '22 07:08 indikasampath2000

@shafreenAnfar @hasithaa @hevayo This improvement is essential to provide a secure deployment option in Choreo. Inability to detect which configurable is sensitive or not, causes us to ask it from the user which is sort of not optimal in Ballerina context but in non-ballerina apps. Can we get an update so that we can plan accordingly?

manjulaRathnayaka avatar Aug 19 '22 10:08 manjulaRathnayaka

Can't we use @display annotation here, with additional meta data? Each stdlib module has to follow the same convention.

hasithaa avatar Aug 31 '22 08:08 hasithaa

+1. We'll come up with additional metadata and discuss it here to finalize them.

indikasampath2000 avatar Aug 31 '22 09:08 indikasampath2000

@hasithaa, I checked the @display definition.

# Denotes general-purpose metadata to customize how Ballerina symbols are displayed in a UI environment.
public const annotation record {
    # label for the Ballerina construct
    string label;
    # icon path relative to module's resource directory
    string iconPath?;
} display on source type, source class,
      source function, source return, source parameter, source field, source listener,
      source var, source const, source annotation, source service;

It allows only label and iconPath as metadata. label is required. We cannot define anything custom. Would it require some change from the Ballerina?

indikasampath2000 avatar Aug 31 '22 09:08 indikasampath2000

@indikasampath2000 But the record is open, you can have additional metadata called, kind/type, etc.. e.g.:

type SomeConfig record {
    string username;
    @display {
        label: "auth token",
        kind: "password"
    }
    string token;
};

@shafreenAnfar @daneshk we have to use the same metadata across all the stdlib.

Also note that, with Update 2, we will introduce, @constraint annotation. It describes constraints on the value, which also useful when generating UI forms.

hasithaa avatar Sep 01 '22 06:09 hasithaa

Ok, my bad. I checked this in Ballerina 2201.0.3 (Swan Lake) and it gave me the following compilation error.

ERROR [main.bal:(44:9,44:13)] invalid key 'kind': identifiers cannot be used as rest field keys, expected a string literal or an expression
error: compilation contains errors

But no errors after updating to Ballerina 2201.1.1 (Swan Lake Update 1)

indikasampath2000 avatar Sep 01 '22 07:09 indikasampath2000

Display annotation syntax for Choreo UI elements rendering

Applied for:

  • Fields in records
  • Configurable variables (or generally any variable?)

Use Case 1: Masking sensitive fields

type Credentials record {
    string username;
    @display {
        label: "auth token",
        mask: true
        sensitive: true
    }
    string token;
};
  • Looking at “mask”, the UI will generate a password type text box which masks whatever typed there. If the display annotation is not there, it is considered mask=false.
  • Looking at “sensitive”, the value backend logic can treat this special (i.e store in Azure key vault). If the display annotation is not there, it is considered sensitive=false.

Use Case 2: Identify file paths

type SSLConfig record {
    string username;
    @display {
        label: "client certificate path",
        kind: filePath
    }
    string clientCert;
};

Looking at “kind”, there will be different UI element renderings. There’s a defined set of kinds considered by Choreo UI.

Possible values for kind:

  • filePath (renders file upload button next to path text box)

(Note: for now we only have filePath, however in future there may be more kinds that is supported by UI rendering logic)

abeykoon avatar Sep 14 '22 04:09 abeykoon

@hasithaa, @abeykoon can we add these fields to the display annotation to reserve them. Otherwise people might use these for other use-cases. Also is the kind attribute an enum ?

hevayo avatar Sep 14 '22 05:09 hevayo

@hevayo +1 to reserve those as optional fields.

IMO, we only need one attribute for both cases, and its values should be a subset of HTML input types.

@hevayo, Since display annotation defined in main symbol space, defining an enum for kind attribute will pollute the main symbol space. Hence I will define it something like, "text"|"date"|"password"|"time"|"file"|"url"|"tel"|"email" kind; There are other kinds we can support too.

hasithaa avatar Sep 14 '22 08:09 hasithaa

+1 to use a union instead of enum.

Also since display annotation can be put to any constructs we should implement a validator to prevent using certain attributes in irrelevant places. ie Using mask attribute inside display annotation added to a service. But validator can come later.

hevayo avatar Sep 14 '22 09:09 hevayo

We had a discussion on above proposal and decided on below

  • sensitive is not used for display purpose, so should not be a part of display annotation. A future platform annotation may support it
  • Introduce one field like kind with a defined set of types. @indikasampath2000 and @abeykoon to come up with a list
  • Validation can come later. If we can agree to a list of words that can come for the value of kind, it is good enough to start

abeykoon avatar Sep 15 '22 07:09 abeykoon

As @abeykoon mentioned, we decided to have single metadata under the @display annotation to solve this problem since the @display is intended for rendering purposes. The data sensitivity has to decide by the user. The relevant tooling rendering these configuration records needs to get that information from the user for the persistent.

The kind metadata would have the following three values by looking at the existing connector configurations.

"text"|"password"|"file" kind;

The default would be "text" when there is no @display annotation for the given field.

Connector Configs Kind
ballerinax/mysql
ballerinax/mssql
ballerinax/oracledb
ballerinax/postgresql
password
crypto:KeyStore#path
crypto:KeyStore#password
crypto:TrustStore#path
crypto:TrustStore#password
password
file
password
file
password
ballerina/http http:CredentialsConfig#password
http:BearerTokenConfig#token
http:OAuth2ClientCredentialsGrantConfig#clientSecret
http:OAuth2PasswordGrantConfig#password
http:OAuth2PasswordGrantConfig#clientSecret
http:OAuth2RefreshTokenGrantConfig#clientSecret
http:OAuth2RefreshTokenGrantConfig#refreshToken
http:OAuth2JwtBearerGrantConfig#clientSecret
crypto:KeyStore#path
crypto:KeyStore#password
crypto:TrustStore#path
crypto:TrustStore#password
password
password
password
password
password
password
password
password
file
password
file
password
Ecosystem handwritten connectors Same as ballerina/http
OpenAPI generated connectors Same as ballerina/http
API Key

Password

indikasampath2000 avatar Sep 15 '22 17:09 indikasampath2000

@shafreenAnfar @daneshk, could you please verify the above list and add if I have missed something?

indikasampath2000 avatar Sep 15 '22 17:09 indikasampath2000

In HTML input type file means, file upload. But in our case, what we need is file-path, which is mapped to url in HTML input types.

hasithaa avatar Sep 16 '22 01:09 hasithaa

No, here we want to give an option to upload the cert and key file. We'll generate a path after uploading the file and mount the file to the generated path at deployment.

indikasampath2000 avatar Sep 16 '22 04:09 indikasampath2000

@hasithaa @hevayo we met a scenario like this.

public type ClientSecureSocket record {|
    boolean enable = true;
    crypto:TrustStore|string cert?;
    crypto:KeyStore|CertKey key?;
    record {|
        Protocol name;
        string[] versions = [];
    |} protocol?;
    record {|
        CertValidationType 'type = OCSP_STAPLING;
        int cacheSize;
        int cacheValidityPeriod;
    |} certValidation?;
    string[] ciphers?;
    boolean verifyHostName = true;
    boolean shareSession = true;
    decimal handshakeTimeout?;
    decimal sessionTimeout?;
|};

If we take crypto:TrustStore|string cert?; The UI functionality needs to be

  1. if selected string type, a text box will be there and content needs to be masked.
  2. if selected crypto:TrustStore type it should display following

public type TrustStore record {| string path; ----> Upload button string password; ----> Should be masked |};

How can we define this functionality when we have an union of a record and a basic type?

abeykoon avatar Sep 29 '22 06:09 abeykoon

I think it is UI Form generation's decision to how to render string or record filed. What we can do is we can put @display { kind : "password" } to the cert to indicate it is a sensitive value. So when users select string, the text box will be masked. But for record filling, masking doesn't make sense and it has to get what have mentioned in thecrypto:TrustStore and use that for rendering.

@hevayo @abeykoon thoughts.

hasithaa avatar Oct 03 '22 09:10 hasithaa