Commit dde1fabc authored by Sietse Ringers's avatar Sietse Ringers
Browse files

DELETE canceled and failed sessions

parent 05746443
......@@ -6,6 +6,7 @@ import (
"strconv"
"strings"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
)
......@@ -84,20 +85,19 @@ func calcVersion(qr *Qr) (string, error) {
// NewSession creates and starts a new IRMA session.
func NewSession(credManager *CredentialManager, qr *Qr, handler Handler) {
version, err := calcVersion(qr)
if err != nil {
handler.Failure(ActionUnknown, &Error{ErrorCode: ErrorProtocolVersionNotSupported, Err: err})
return
}
session := &session{
Version: Version(version),
Action: Action(qr.Type),
ServerURL: qr.URL,
Handler: handler,
transport: NewHTTPTransport(qr.URL),
credManager: credManager,
}
version, err := calcVersion(qr)
if err != nil {
session.fail(&Error{ErrorCode: ErrorProtocolVersionNotSupported, Err: err})
return
}
session.Version = Version(version)
// Check if the action is one of the supported types
switch session.Action {
......@@ -107,7 +107,7 @@ func NewSession(credManager *CredentialManager, qr *Qr, handler Handler) {
case ActionUnknown:
fallthrough
default:
handler.Failure(ActionUnknown, &Error{ErrorCode: ErrorUnknownAction, Err: nil, Info: string(session.Action)})
session.fail(&Error{ErrorCode: ErrorUnknownAction, Err: nil, Info: string(session.Action)})
return
}
......@@ -120,6 +120,12 @@ func NewSession(credManager *CredentialManager, qr *Qr, handler Handler) {
return
}
func (session *session) fail(err *Error) {
session.transport.Delete()
err.Err = errors.Wrap(err.Err, 0)
session.Handler.Failure(session.Action, err)
}
// start retrieves the first message in the IRMA protocol, checks if we can perform
// the request, and informs the user of the outcome.
func (session *session) start() {
......@@ -129,7 +135,7 @@ func (session *session) start() {
info := &SessionInfo{}
Err := session.transport.Get("jwt", info)
if Err != nil {
session.Handler.Failure(session.Action, Err.(*Error))
session.fail(Err.(*Error))
return
}
......@@ -145,7 +151,7 @@ func (session *session) start() {
}
server, err := jwtDecode(info.Jwt, session.jwt)
if err != nil {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorInvalidJWT, Err: err})
session.fail(&Error{ErrorCode: ErrorInvalidJWT, Err: err})
return
}
session.irmaSession = session.jwt.IrmaSession()
......@@ -161,6 +167,7 @@ func (session *session) start() {
missing := session.credManager.CheckSatisfiability(session.irmaSession.DisjunctionList())
if len(missing) > 0 {
session.Handler.UnsatisfiableRequest(session.Action, missing)
// TODO: session.transport.Delete() on dialog cancel
return
}
......@@ -185,6 +192,7 @@ func (session *session) start() {
func (session *session) do(proceed bool) {
if !proceed {
session.transport.Delete()
session.Handler.Cancelled(session.Action)
return
}
......@@ -202,7 +210,7 @@ func (session *session) do(proceed bool) {
message, err = session.credManager.IssueCommitments(session.irmaSession.(*IssuanceRequest))
}
if err != nil {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorCrypto, Err: err})
session.fail(&Error{ErrorCode: ErrorCrypto, Err: err})
return
}
session.sendResponse(message)
......@@ -218,7 +226,7 @@ func (session *session) do(proceed bool) {
builders, err = session.credManager.IssuanceProofBuilders(session.irmaSession.(*IssuanceRequest))
}
if err != nil {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorCrypto, Err: err})
session.fail(&Error{ErrorCode: ErrorCrypto, Err: err})
}
startKeyshareSession(session.credManager, session.irmaSession, builders, session, session.Handler)
......@@ -230,18 +238,16 @@ func (session *session) KeyshareDone(message interface{}) {
}
func (session *session) KeyshareCancelled() {
session.transport.Delete()
session.Handler.Cancelled(session.Action)
}
func (session *session) KeyshareBlocked(duration int) {
session.Handler.Failure(
session.Action,
&Error{ErrorCode: ErrorKeyshareBlocked, Info: strconv.Itoa(duration)},
)
session.fail(&Error{ErrorCode: ErrorKeyshareBlocked, Info: strconv.Itoa(duration)})
}
func (session *session) KeyshareError(err error) {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorKeyshare, Err: err})
session.fail(&Error{ErrorCode: ErrorKeyshare, Err: err})
}
type disclosureResponse string
......@@ -254,21 +260,21 @@ func (session *session) sendResponse(message interface{}) {
case ActionDisclosing:
var response disclosureResponse
if err = session.transport.Post("proofs", &response, message); err != nil {
session.Handler.Failure(session.Action, err.(*Error))
session.fail(err.(*Error))
return
}
if response != "VALID" {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorRejected, Info: string(response)})
session.fail(&Error{ErrorCode: ErrorRejected, Info: string(response)})
return
}
case ActionIssuing:
response := []*gabi.IssueSignatureMessage{}
if err = session.transport.Post("commitments", &response, message); err != nil {
session.Handler.Failure(session.Action, err.(*Error))
session.fail(err.(*Error))
return
}
if err = session.credManager.ConstructCredentials(response, session.irmaSession.(*IssuanceRequest)); err != nil {
session.Handler.Failure(session.Action, &Error{Err: err, ErrorCode: ErrorCrypto})
session.fail(&Error{Err: err, ErrorCode: ErrorCrypto})
return
}
}
......
......@@ -41,7 +41,7 @@ func (transport *HTTPTransport) SetHeader(name, val string) {
}
func (transport *HTTPTransport) request(url string, method string, result interface{}, object interface{}) error {
if method != http.MethodPost && method != http.MethodGet {
if method != http.MethodPost && method != http.MethodGet && method != http.MethodDelete {
panic("Unsupported HTTP method " + method)
}
if method == http.MethodGet && object != nil {
......@@ -53,9 +53,6 @@ func (transport *HTTPTransport) request(url string, method string, result interf
if object != nil {
var objstr string
if objstr, isstr = object.(string); isstr {
if verbose {
fmt.Printf("GET %s\n", url)
}
reader = bytes.NewBuffer([]byte(objstr))
} else {
marshaled, err := json.Marshal(object)
......@@ -63,10 +60,14 @@ func (transport *HTTPTransport) request(url string, method string, result interf
return &Error{Err: err, ErrorCode: ErrorSerialization}
}
if verbose {
fmt.Printf("POST %s: %s\n", url, string(marshaled))
fmt.Printf("%s %s: %s\n", method, url, string(marshaled))
}
reader = bytes.NewBuffer(marshaled)
}
} else {
if verbose {
fmt.Printf("%s %s\n", method, url)
}
}
req, err := http.NewRequest(method, transport.Server+url, reader)
......@@ -91,6 +92,10 @@ func (transport *HTTPTransport) request(url string, method string, result interf
return &Error{ErrorCode: ErrorTransport, Err: err}
}
if method == http.MethodDelete {
return nil
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return &Error{ErrorCode: ErrorServerResponse, Err: err, Status: res.StatusCode}
......@@ -133,6 +138,6 @@ func (transport *HTTPTransport) Get(url string, result interface{}) error {
}
// Delete performs a DELETE.
func (transport *HTTPTransport) Delete(url string) {
// TODO
func (transport *HTTPTransport) Delete() {
transport.request("", http.MethodDelete, nil, nil)
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment