<div dir="ltr"><span style="font-size:12.8000001907349px">We've been working on adding external user support to juju</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">and a discussion arose from a throwaway comment on the</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">IRC channel:</span><br style="font-size:12.8000001907349px"><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">"The difference between Canonical() and Id() seems confusing to me"</span><br style="font-size:12.8000001907349px"><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">The comment referred to two names.UserTag methods</span><div style="font-size:12.8000001907349px">(defined in the package <a href="http://github.com/juju/names" target="_blank">github.com/juju/names</a>).<br><div><br>The Canonical method (†) returns the "canonical" form of<br>a user always with an @ symbol. For example bob@local (a local user),<div>bob@somewhere (an external user).<div><br><div>The Id method returns whatever id the UserTag was created with, which</div><div>preserves a basic invariant of the Tag interface - NewUserTag(x).Id() == x</div><div>for any valid user id x.</div><div><br></div><div>It seemed to us that the reason for the confusing Canonical method</div><div>was entirely because we have two alternative spellings</div><div>for a local user, "bob" and "bob@local".</div><div><br></div><div>As a solution to this, we propose that there be exactly</div><div>one spelling of a local user - plain "bob", and</div><div>that *any* username with an @ domain should be considered</div><div>to be external.</div><div><br></div><div>If we do this, there is no need for a Canonical method</div><div>because every user name is inherently in canonical form.</div><div>That is, there is no way to get it wrong.</div><div><br></div><div>It is also consistent with the way that user names are currently stored</div><div>in the database - they are stored without the @local suffix,</div><div>and we will soon want to store information about external</div><div>users in the same database, so using the above suggested</div><div>canonical form means that no database migration is necessary.</div><div><br></div><div>We believe that this is also a very intuitive model:</div><div><br></div><div><b><i>    </i>A username is external if and only if it has an <i>@domain</i> suffix.</b></div><div><br></div><div>We have a working feature branch with this change applied,</div><div>but we'd be grateful for any feedback on the proposal.</div><div><br></div><div>  cheers,</div><div>    rog.</div><div><br>(†) until this morning, this was named Username, but we<br>changed it because we found the fact that Username()<br>doesn't return a string that satisfies IsValidUserName<br>somewhat confusing.</div></div></div></div></div></div>