nats-io / nats-architecture-and-design

Architecture and Design Docs
Apache License 2.0
177 stars 20 forks source link

Accept encoded connection urls. #123

Open scottf opened 1 year ago

scottf commented 1 year ago

Overview

It is valid to have the uri encoded.

tls://user:Rmwuukd0QsJI%5ERMkFGHz1J7vjz0A%2A27oCA%23j6%21WYf%23@host:4222

where the password is actually

Rmwuukd0QsJI^RMkFGHz1J7vjz0A*27oCA#j6!WYf#

Clients and Tools

Other Tasks

Client authors please update with your progress. If you open issues in your own repositories as a result of this request, please link them to this one by pasting the issue URL in a comment or main issue description.

scottf commented 1 year ago

I'm building unit tests against this:

authorization {
  ENC = {
    publish: {
      allow: [
                "sub.>"
                ]
    }
    subscribe: {
      allow: [
                "sub.>"
                ]
    }
  }
  users = [
    {user: space, password: 'space space', permissions: $ENC}
    {user: quote, password: "quote'quote", permissions: $ENC}
    {user: colon, password: "colon:colon", permissions: $ENC}
    {user: slash, password: 'slash/slash', permissions: $ENC}
    {user: question, password: 'question?question', permissions: $ENC}
    {user: pound, password: 'pound#pound', permissions: $ENC}
    {user: sqleft, password: 'sqleft[sqleft', permissions: $ENC}
    {user: sqright, password: 'sqright]sqright', permissions: $ENC}
    {user: at, password: 'at@at', permissions: $ENC}
    {user: bang, password: 'bang!bang', permissions: $ENC}
    {user: dollar, password: 'dollar$dollar', permissions: $ENC}
    {user: amp, password: 'amp&amp', permissions: $ENC}
    {user: comma, password: 'comma,comma', permissions: $ENC}
    {user: parenleft, password: 'parenleft(parenleft', permissions: $ENC}
    {user: parentright, password: 'parentright)parentright', permissions: $ENC}
    {user: asterix, password: 'asterix*asterix', permissions: $ENC}
    {user: plus, password: 'plus+plus', permissions: $ENC}
    {user: semi, password: 'semi;semi', permissions: $ENC}
    {user: eq, password: 'eq=eq', permissions: $ENC}
    {user: pct, password: 'pct%pct', permissions: $ENC}
  ]
}
scottf commented 1 year ago

Data

Raw Encoded
space space space%20space
colon:colon colon%3Acolon
quote'quote quote%27quote
slash/slash slash%2Fslash
question?question question%3Fquestion
pound#pound pound%23pound
sqleft[sqleft sqleft%5Bsqleft
sqright]sqright sqright%5Dsqright
at@at at%40at
bang!bang bang%21bang
dollar$dollar dollar%24dollar
amp&amp amp%26amp
comma,comma comma%2Ccomma
parenleft(parenleft parenleft%28parenleft
parentright)parentright parentright%29parentright
asterix*asterix asterix%2Aasterix
plus+plus plus%2Bplus
semi;semi semi%3Bsemi
eq=eq eq%3Deq
pct%pct pct%25pct
wallyqs commented 1 year ago

This ADR documents current Go client behavior, for example given the following conf:

authorization {
  users = [
    {
      user: "user",
      pass: "Rmwuukd0QsJI^RMkFGHz1J7vjz0A*27oCA#j6!WYf#"
    }
  ]
}

a Go client can connect with the following nats.Connect syntax using the URL encoded:

nats.Connect("tls://user:Rmwuukd0QsJI%5ERMkFGHz1J7vjz0A%2A27oCA%23j6%21WYf%23@127.0.0.1:4222")

Then when sending CONNECT this is sent decoded to the server (matches what is in authorization config):

CONNECT {"verbose":false,"pedantic":false,"user":"user","pass":"Rmwuukd0QsJI^RMkFGHz1J7vjz0A*27oCA#j6!WYf#","tls_required":false,"name":"","lang":"go","version":"1.16.0","protocol":1,"echo":true,"headers":true,"no_responders":true}

We rely on the net/url package to parse this, so passing a raw URI will fail to parse:

nats.Connect("tls://user:Rmwuukd0QsJI^RMkFGHz1J7vjz0A*27oCA#j6!WYf#@127.0.0.1:4222")
// Result:
Error: parse "tls://user:Rmwuukd0QsJI^RMkFGHz1J7vjz0A*27oCA": invalid port ":Rmwuukd0QsJI^RMkFGHz1J7vjz0A*27oCA" after host
scottf commented 1 year ago

Java is fine, .NET needs fixing.