in lib/cli/cli.go [260:327]
func (h *RegisterHandler) Post(r *http.Request, name string) (proto.Message, error) {
if name == autoGenerate {
name = uuid.New()
}
email := httputils.QueryParam(r, "email")
if len(email) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "missing email address parameter")
}
if _, err := mail.ParseAddress(email); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid email address %q: %v", email, err)
}
scope := httputils.QueryParamWithDefault(r, "scope", "openid profile email offline")
cat := time.Now()
exp := cat.Add(ttl)
catProto, err := ptypes.TimestampProto(cat)
if err != nil {
return nil, status.Errorf(codes.Internal, "cannot generate iat timestamp: %v", err)
}
expProto, err := ptypes.TimestampProto(exp)
if err != nil {
return nil, status.Errorf(codes.Internal, "cannot generate exp timestamp: %v", err)
}
unique := uuid.New() + "/" + cat.Format(time.RFC3339Nano) + "/" + strconv.FormatUint(rand.Uint64(), 16)
hash := sha3.Sum256([]byte(unique))
secret := hex.EncodeToString(hash[:])
encrypted, err := h.crypt.Encrypt(r.Context(), []byte(secret), "")
if err != nil {
return nil, status.Errorf(codes.Internal, "cannot generate secret: %v", err)
}
a, err := auth.FromContext(r.Context())
if err != nil {
return nil, status.Errorf(codes.Internal, "cannot obtain request context: %v", err)
}
u, err := url.Parse(h.authURL)
if err != nil {
return nil, status.Errorf(codes.Internal, "invalid redirect URL: %v", err)
}
q := u.Query()
q.Set("grant_type", "authorization_code")
q.Set("response_type", "code")
q.Set("client_id", a.ClientID)
q.Set("scope", scope)
q.Set("state", name)
q.Set("redirect_uri", h.accept)
u.RawQuery = q.Encode()
h.save = &cpb.CliState{
Id: name,
Email: email,
EncryptedSecret: encrypted,
ClientId: a.ClientID,
Scope: scope,
AuthUrl: u.String(),
CreatedAt: catProto,
ExpiresAt: expProto,
State: storage.StateActive,
}
// Return the non-encrypted secret whereas `h.save` above will have the secret encrypted.
return &cpb.CliState{
Id: h.save.Id,
Email: h.save.Email,
Secret: secret,
Scope: scope,
AuthUrl: strings.Replace(h.cliAuthURL, "{name}", name, -1),
CreatedAt: catProto,
ExpiresAt: expProto,
}, nil
}