WSPR: Intercept publicKeyCaveat and handle in go
MultiPart: 2/2
Change-Id: I1cf73def98e6776179feab9ed1286d3a3a7c2d9c
diff --git a/services/wsprd/ipc/server/server.go b/services/wsprd/ipc/server/server.go
index f6cf9a4..3c3bcc8 100644
--- a/services/wsprd/ipc/server/server.go
+++ b/services/wsprd/ipc/server/server.go
@@ -331,7 +331,7 @@
// It resolves each []security.Caveat in cavs to an error (or nil) and collects them in a slice.
// TODO(ataly, ashankar, bprosnitz): Update this method so tha it also conveys the CallSide to
// JavaScript.
-func (s *Server) wsprCaveatValidator(call security.Call, _ security.CallSide, cavs [][]security.Caveat) []error {
+func (s *Server) validateCavsInJavascript(call security.Call, _ security.CallSide, cavs [][]security.Caveat) []error {
flow := s.helper.CreateNewFlow(s, nil)
req := CaveatValidationRequest{
Call: s.convertSecurityCall(call, false),
@@ -374,6 +374,61 @@
}
}
+// wsprCaveatValidator validates caveats for javascript.
+// Certain caveats (PublicKeyThirdPartyCaveatX) are intercepted and handled in go.
+// This call validateCavsInJavascript to process the remaining caveats in javascript.
+func (s *Server) wsprCaveatValidator(call security.Call, callSide security.CallSide, cavs [][]security.Caveat) []error {
+ type validationStatus struct {
+ err error
+ isSet bool
+ }
+ valStatus := make([]validationStatus, len(cavs))
+
+ var caveatChainsToValidate [][]security.Caveat
+nextCav:
+ for i, chainCavs := range cavs {
+ var newChainCavs []security.Caveat
+ for _, cav := range chainCavs {
+ switch cav.Id {
+ case security.PublicKeyThirdPartyCaveatX.Id:
+ res := cav.Validate(call, callSide)
+ if res != nil {
+ valStatus[i] = validationStatus{
+ err: res,
+ isSet: true,
+ }
+ continue nextCav
+ }
+ default:
+ newChainCavs = append(newChainCavs, cav)
+ }
+ }
+ if len(newChainCavs) == 0 {
+ valStatus[i] = validationStatus{
+ err: nil,
+ isSet: true,
+ }
+ } else {
+ caveatChainsToValidate = append(caveatChainsToValidate, newChainCavs)
+ }
+ }
+
+ jsRes := s.validateCavsInJavascript(call, callSide, caveatChainsToValidate)
+
+ outResults := make([]error, len(cavs))
+ jsIndex := 0
+ for i, status := range valStatus {
+ if status.isSet {
+ outResults[i] = status.err
+ } else {
+ outResults[i] = jsRes[jsIndex]
+ jsIndex++
+ }
+ }
+
+ return outResults
+}
+
func (s *Server) convertSecurityCall(call security.Call, includeBlessingStrings bool) SecurityCall {
// TODO(bprosnitz) Local/Remote Endpoint should always be non-nil, but isn't
// due to a TODO in vc/auth.go