github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/user/utils.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package user 5 6 import ( 7 "encoding/asn1" 8 "encoding/base64" 9 10 "github.com/juju/errors" 11 12 "github.com/juju/juju/cmd/modelcmd" 13 "github.com/juju/juju/jujuclient" 14 ) 15 16 func generateUserControllerAccessToken(command modelcmd.ControllerCommandBase, username string, secretKey []byte) (string, error) { 17 controllerName, err := command.ControllerName() 18 if err != nil { 19 return "", errors.Trace(err) 20 } 21 22 // Generate the base64-encoded string for the user to pass to 23 // "juju register". We marshal the information using ASN.1 24 // to keep the size down, since we need to encode binary data. 25 controllerDetails, err := command.ClientStore().ControllerByName(controllerName) 26 if err != nil { 27 return "", errors.Trace(err) 28 } 29 registrationInfo := jujuclient.RegistrationInfo{ 30 User: username, 31 Addrs: controllerDetails.APIEndpoints, 32 SecretKey: secretKey, 33 ControllerName: controllerName, 34 } 35 registrationData, err := asn1.Marshal(registrationInfo) 36 if err != nil { 37 return "", errors.Trace(err) 38 } 39 40 // Use URLEncoding so we don't get + or / in the string, 41 // and pad with zero bytes so we don't get =; this all 42 // makes it easier to copy & paste in a terminal. 43 // 44 // The embedded ASN.1 data is length-encoded, so the 45 // padding will not complicate decoding. 46 remainder := len(registrationData) % 3 47 if remainder != 0 { 48 var pad [3]byte 49 registrationData = append(registrationData, pad[:3-remainder]...) 50 } 51 return base64.URLEncoding.EncodeToString(registrationData), nil 52 }