diff --git a/fs/cache.go b/fs/cache.go index 0798924..48c9668 100644 --- a/fs/cache.go +++ b/fs/cache.go @@ -17,6 +17,7 @@ type MetadataCacheTimeoutSetting struct { Inherit bool } +// CacheConfig defines cache config type CacheConfig struct { Timeout time.Duration // cache timeout CleanupTime time.Duration // @@ -30,6 +31,7 @@ type CacheConfig struct { StartNewTransaction bool } +// NewDefaultCacheConfig creates a new default CacheConfig func NewDefaultCacheConfig() CacheConfig { return CacheConfig{ Timeout: FileSystemTimeoutDefault, diff --git a/icommands/environment.go b/icommands/environment.go index a06a818..89151d9 100644 --- a/icommands/environment.go +++ b/icommands/environment.go @@ -198,7 +198,7 @@ func (manager *ICommandsEnvironmentManager) Load(processID int) error { // continue } else { authScheme := types.GetAuthScheme(manager.Environment.AuthenticationScheme) - if authScheme == types.AuthSchemePAM { + if authScheme.IsPAM() { manager.Password = "" manager.PamToken = password } else { @@ -247,7 +247,7 @@ func (manager *ICommandsEnvironmentManager) SaveEnvironment() error { authScheme := types.GetAuthScheme(manager.Environment.AuthenticationScheme) password := manager.Password - if authScheme == types.AuthSchemePAM { + if authScheme.IsPAM() { password = manager.PamToken } diff --git a/irods/connection/connection.go b/irods/connection/connection.go index c034679..e4e4741 100644 --- a/irods/connection/connection.go +++ b/irods/connection/connection.go @@ -119,6 +119,10 @@ func (conn *IRODSConnection) SupportParallelUpload() bool { return conn.serverVersion.HasHigherVersionThan(4, 2, 9) } +func (conn *IRODSConnection) requirePAMPassword() bool { + return conn.serverVersion.HasHigherVersionThan(4, 3, 0) +} + func (conn *IRODSConnection) requiresCSNegotiation() bool { return conn.account.ClientServerNegotiation } @@ -203,27 +207,13 @@ func (conn *IRODSConnection) setSocketOpt(socket net.Conn, bufferSize int) { } } -// Connect connects to iRODS -func (conn *IRODSConnection) Connect() error { +func (conn *IRODSConnection) connectTCP() error { logger := log.WithFields(log.Fields{ "package": "connection", "struct": "IRODSConnection", - "function": "Connect", + "function": "connectTCP", }) - conn.connected = false - - conn.account.FixAuthConfiguration() - - err := conn.account.Validate() - if err != nil { - return xerrors.Errorf("invalid account (%q): %w", err.Error(), types.NewConnectionConfigError(conn.account)) - } - - // lock the connection - conn.Lock() - defer conn.Unlock() - server := fmt.Sprintf("%s:%d", conn.account.Host, conn.account.Port) logger.Debugf("Connecting to %s", server) @@ -250,16 +240,37 @@ func (conn *IRODSConnection) Connect() error { } conn.socket = socket - var irodsVersion *types.IRODSVersion + return nil +} - if conn.requiresCSNegotiation() { - // client-server negotiation - irodsVersion, err = conn.connectWithCSNegotiation() - } else { - // No client-server negotiation - irodsVersion, err = conn.connectWithoutCSNegotiation() +// Connect connects to iRODS +func (conn *IRODSConnection) Connect() error { + logger := log.WithFields(log.Fields{ + "package": "connection", + "struct": "IRODSConnection", + "function": "Connect", + }) + + conn.account.FixAuthConfiguration() + + err := conn.account.Validate() + if err != nil { + return xerrors.Errorf("invalid account (%q): %w", err.Error(), types.NewConnectionConfigError(conn.account)) + } + + conn.connected = false + + // lock the connection + conn.Lock() + defer conn.Unlock() + + // connect TCP + err = conn.connectTCP() + if err != nil { + return err } + irodsVersion, err := conn.startup() if err != nil { connErr := xerrors.Errorf("failed to startup an iRODS connection to server %q and port %d (%s): %w", conn.account.Host, conn.account.Port, err.Error(), types.NewConnectionError()) logger.Errorf("%+v", connErr) @@ -277,11 +288,38 @@ func (conn *IRODSConnection) Connect() error { err = conn.loginNative() case types.AuthSchemeGSI: err = conn.loginGSI() - case types.AuthSchemePAM: + case types.AuthSchemePAM, types.AuthSchemePAMPassword: if len(conn.account.PamToken) > 0 { err = conn.loginPAMWithToken() } else { err = conn.loginPAMWithPassword() + if err != nil { + connErr := xerrors.Errorf("failed to login to irods using PAM authentication: %w", err) + logger.Errorf("%+v", connErr) + return connErr + } + + // reconnect when success + conn.disconnectNow() + + // connect TCP + err = conn.connectTCP() + if err != nil { + return err + } + + _, err = conn.startup() + if err != nil { + connErr := xerrors.Errorf("failed to startup an iRODS connection to server %q and port %d (%s): %w", conn.account.Host, conn.account.Port, err.Error(), types.NewConnectionError()) + logger.Errorf("%+v", connErr) + _ = conn.disconnectNow() + if conn.metrics != nil { + conn.metrics.IncreaseCounterForConnectionFailures(1) + } + return connErr + } + + err = conn.loginPAMWithToken() } default: err = xerrors.Errorf("unknown Authentication Scheme %q: %w", conn.account.AuthenticationScheme, types.NewConnectionConfigError(conn.account)) @@ -296,7 +334,7 @@ func (conn *IRODSConnection) Connect() error { if conn.account.UseTicket() { req := message.NewIRODSMessageTicketAdminRequest("session", conn.account.Ticket) - err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageTicketAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received supply ticket error (%s): %w", err.Error(), types.NewAuthError(conn.account)) } @@ -304,33 +342,46 @@ func (conn *IRODSConnection) Connect() error { conn.connected = true conn.lastSuccessfulAccess = time.Now() - return nil } -func (conn *IRODSConnection) connectWithCSNegotiation() (*types.IRODSVersion, error) { +func (conn *IRODSConnection) startup() (*types.IRODSVersion, error) { logger := log.WithFields(log.Fields{ "package": "connection", "struct": "IRODSConnection", - "function": "connectWithCSNegotiation", + "function": "startup", }) - // Get client negotiation policy clientPolicy := types.CSNegotiationRequireTCP - if len(conn.account.CSNegotiationPolicy) > 0 { - clientPolicy = conn.account.CSNegotiationPolicy + if conn.requiresCSNegotiation() { + // Get client negotiation policy + if len(conn.account.CSNegotiationPolicy) > 0 { + clientPolicy = conn.account.CSNegotiationPolicy + } } + logger.Debug("Start up an iRODS connection") + // Send a startup message - logger.Debug("Start up a connection with CS Negotiation") + startup := message.NewIRODSMessageStartupPack(conn.account, conn.applicationName, conn.requiresCSNegotiation()) - startup := message.NewIRODSMessageStartupPack(conn.account, conn.applicationName, true) - err := conn.RequestWithoutResponse(startup) - if err != nil { - return nil, xerrors.Errorf("failed to send startup (%s): %w", err.Error(), types.NewConnectionError()) + if conn.requiresCSNegotiation() { + err := conn.RequestWithoutResponse(startup) + if err != nil { + return nil, xerrors.Errorf("failed to send startup (%s): %w", err.Error(), types.NewConnectionError()) + } + } else { + // no cs negotiation + version := message.IRODSMessageVersion{} + err := conn.Request(startup, &version, nil) + if err != nil { + return nil, xerrors.Errorf("failed to receive version message (%s): %w", err.Error(), types.NewConnectionError()) + } + + return version.GetVersion(), nil } - // Server responds with negotiation response + // cs negotiation response negotiationMessage, err := conn.ReadMessage(nil) if err != nil { return nil, xerrors.Errorf("failed to receive negotiation message (%s): %w", err.Error(), types.NewConnectionError()) @@ -394,27 +445,7 @@ func (conn *IRODSConnection) connectWithCSNegotiation() (*types.IRODSVersion, er } return nil, xerrors.Errorf("unknown response message %q: %w", negotiationMessage.Body.Type, types.NewConnectionError()) -} - -func (conn *IRODSConnection) connectWithoutCSNegotiation() (*types.IRODSVersion, error) { - logger := log.WithFields(log.Fields{ - "package": "connection", - "struct": "IRODSConnection", - "function": "connectWithoutCSNegotiation", - }) - - // No client-server negotiation - // Send a startup message - logger.Debug("Start up connection without CS Negotiation") - - startup := message.NewIRODSMessageStartupPack(conn.account, conn.applicationName, false) - version := message.IRODSMessageVersion{} - err := conn.Request(startup, &version, nil) - if err != nil { - return nil, xerrors.Errorf("failed to receive version message (%s): %w", err.Error(), types.NewConnectionError()) - } - return version.GetVersion(), nil } func (conn *IRODSConnection) sslStartup() error { @@ -476,7 +507,7 @@ func (conn *IRODSConnection) sslStartup() error { // Send a shared secret sslSharedSecret := message.NewIRODSMessageSSLSharedSecret(encryptionKey) - err = conn.RequestWithoutResponseNoXML(sslSharedSecret) + err = conn.RequestWithoutResponse(sslSharedSecret) if err != nil { return xerrors.Errorf("failed to send ssl shared secret message (%s): %w", err.Error(), types.NewConnectionError()) } @@ -490,7 +521,7 @@ func (conn *IRODSConnection) login(password string) error { // authenticate authRequest := message.NewIRODSMessageAuthRequest() authChallenge := message.IRODSMessageAuthChallengeResponse{} - err := conn.Request(authRequest, &authChallenge, nil) + err := conn.RequestAndCheck(authRequest, &authChallenge, nil) if err != nil { return xerrors.Errorf("failed to receive authentication challenge message body (%s): %w", err.Error(), types.NewAuthError(conn.account)) } @@ -551,7 +582,7 @@ func (conn *IRODSConnection) loginPAMWithPassword() error { ttl := conn.account.PamTTL if ttl < 0 { - ttl = 0 // decided by server + ttl = 0 // server decides } pamPassword := conn.getSafePAMPassword(conn.account.Password) @@ -562,41 +593,43 @@ func (conn *IRODSConnection) loginPAMWithPassword() error { authContext := strings.Join([]string{userKV, passwordKV, ttlKV}, ";") - useDedicatedPAMApi := false - if strings.ContainsAny(pamPassword, ";=") { - useDedicatedPAMApi = true - } else { - // from python-irodsclient code - if len(authContext) >= 1024+64 { - useDedicatedPAMApi = true - } + useDedicatedPAMApi := true + if conn.requirePAMPassword() { + useDedicatedPAMApi = strings.ContainsAny(pamPassword, ";=") || len(authContext) >= 1024+64 } // authenticate pamToken := "" + if useDedicatedPAMApi { + logger.Debugf("use dedicated PAM api") + pamAuthRequest := message.NewIRODSMessagePamAuthRequest(conn.account.ClientUser, pamPassword, ttl) pamAuthResponse := message.IRODSMessagePamAuthResponse{} - err := conn.Request(pamAuthRequest, &pamAuthResponse, nil) + err := conn.RequestAndCheck(pamAuthRequest, &pamAuthResponse, nil) if err != nil { - return xerrors.Errorf("failed to receive an authentication challenge message (%s): %w", err.Error(), types.NewAuthError(conn.account)) + return xerrors.Errorf("failed to receive a PAM token (%s): %w", err.Error(), types.NewAuthError(conn.account)) } pamToken = pamAuthResponse.GeneratedPassword } else { + logger.Debugf("use auth plugin api: scheme %q", string(types.AuthSchemePAM)) + pamAuthRequest := message.NewIRODSMessageAuthPluginRequest(string(types.AuthSchemePAM), authContext) pamAuthResponse := message.IRODSMessageAuthPluginResponse{} - err := conn.Request(pamAuthRequest, &pamAuthResponse, nil) + err := conn.RequestAndCheck(pamAuthRequest, &pamAuthResponse, nil) if err != nil { - return xerrors.Errorf("failed to receive an authentication challenge message (%s): %w", err.Error(), types.NewAuthError(conn.account)) + return xerrors.Errorf("failed to receive a PAM token (%s): %w", err.Error(), types.NewAuthError(conn.account)) } - pamToken = pamAuthResponse.Result + pamToken = string(pamAuthResponse.GeneratedPassword) } // save irods generated password for possible future use conn.account.PamToken = pamToken + // disconnect and connect + // retry native auth with generated password return conn.login(conn.account.PamToken) } @@ -1053,6 +1086,7 @@ func (conn *IRODSConnection) poorMansEndTransaction(dummyCol string, commit bool if commit { request.AddKeyVal(common.COLLECTION_TYPE_KW, "NULL_SPECIAL_VALUE") } + response := message.IRODSMessageModifyCollectionResponse{} err := conn.Request(request, &response, nil) if err != nil { diff --git a/irods/connection/request_response.go b/irods/connection/request_response.go index 6dada0b..c21f2dc 100644 --- a/irods/connection/request_response.go +++ b/irods/connection/request_response.go @@ -9,11 +9,13 @@ import ( // Request is an interface for calling iRODS RPC. type Request interface { GetMessage() (*message.IRODSMessage, error) + GetXMLCorrector() message.XMLCorrector } // Response is an interface for response of iRODS RPC Call. type Response interface { - FromMessage(*message.IRODSMessage) error + FromMessage(message *message.IRODSMessage) error + GetXMLCorrector() message.XMLCorrector } // CheckErrorResponse is a Response on which CheckError can be called. @@ -32,6 +34,14 @@ type RequestResponsePair struct { Error error } +func (conn *IRODSConnection) useNewXML() bool { + if conn.serverVersion == nil { + return true + } + + return conn.serverVersion.HasHigherVersionThan(4, 2, 8) +} + // Request sends a request and expects a response. // bsBuffer is optional func (conn *IRODSConnection) Request(request Request, response Response, bsBuffer []byte) error { @@ -44,7 +54,7 @@ func (conn *IRODSConnection) RequestWithTrackerCallBack(request Request, respons // set transaction dirty conn.SetTransactionDirty(true) - requestMessage, err := conn.getRequestMessage(request, true, false) + requestMessage, err := conn.getRequestMessage(request) if err != nil { if conn.metrics != nil { conn.metrics.IncreaseCounterForRequestResponseFailures(1) @@ -70,7 +80,11 @@ func (conn *IRODSConnection) RequestWithTrackerCallBack(request Request, respons return xerrors.Errorf("failed to receive a response message: %w", err) } - err = conn.getResponse(responseMessage, response, true) + //logger.Debugf("response: %#v", responseMessage) + //logger.Debugf("response header: %#v", responseMessage.Header) + //logger.Debugf("response body: %#v", responseMessage.Body) + + err = conn.getResponse(responseMessage, response) if err != nil { if conn.metrics != nil { conn.metrics.IncreaseCounterForRequestResponseFailures(1) @@ -105,7 +119,7 @@ func (conn *IRODSConnection) RequestAsyncWithTrackerCallBack(rrChan chan Request continue } - requestMessage, err := conn.getRequestMessage(pair.Request, true, false) + requestMessage, err := conn.getRequestMessage(pair.Request) if err != nil { if conn.metrics != nil { conn.metrics.IncreaseCounterForRequestResponseFailures(1) @@ -166,7 +180,7 @@ func (conn *IRODSConnection) RequestAsyncWithTrackerCallBack(rrChan chan Request continue } - err = conn.getResponse(responseMessage, pair.Response, true) + err = conn.getResponse(responseMessage, pair.Response) if err != nil { if conn.metrics != nil { conn.metrics.IncreaseCounterForRequestResponseFailures(1) @@ -185,49 +199,9 @@ func (conn *IRODSConnection) RequestAsyncWithTrackerCallBack(rrChan chan Request return outputPair } -// RequestForPassword sends a request and expects a response. XML escape only for '&' -// bsBuffer is optional -func (conn *IRODSConnection) RequestForPassword(request Request, response Response, bsBuffer []byte) error { - requestMessage, err := conn.getRequestMessage(request, true, true) - if err != nil { - if conn.metrics != nil { - conn.metrics.IncreaseCounterForRequestResponseFailures(1) - } - return err - } - - err = conn.SendMessage(requestMessage) - if err != nil { - if conn.metrics != nil { - conn.metrics.IncreaseCounterForRequestResponseFailures(1) - } - return xerrors.Errorf("failed to send a request message: %w", err) - } - - // Server responds with results - // external bs buffer - responseMessage, err := conn.ReadMessage(bsBuffer) - if err != nil { - if conn.metrics != nil { - conn.metrics.IncreaseCounterForRequestResponseFailures(1) - } - return xerrors.Errorf("failed to receive a response message: %w", err) - } - - err = conn.getResponse(responseMessage, response, true) - if err != nil { - if conn.metrics != nil { - conn.metrics.IncreaseCounterForRequestResponseFailures(1) - } - return xerrors.Errorf("failed to parse response message: %w", err) - } - - return nil -} - // RequestWithoutResponse sends a request but does not wait for a response. func (conn *IRODSConnection) RequestWithoutResponse(request Request) error { - requestMessage, err := conn.getRequestMessage(request, true, false) + requestMessage, err := conn.getRequestMessage(request) if err != nil { if conn.metrics != nil { conn.metrics.IncreaseCounterForRequestResponseFailures(1) @@ -246,27 +220,6 @@ func (conn *IRODSConnection) RequestWithoutResponse(request Request) error { return nil } -// RequestWithoutResponseNoXML sends a request but does not wait for a response. -func (conn *IRODSConnection) RequestWithoutResponseNoXML(request Request) error { - requestMessage, err := conn.getRequestMessage(request, false, false) - if err != nil { - if conn.metrics != nil { - conn.metrics.IncreaseCounterForRequestResponseFailures(1) - } - return xerrors.Errorf("failed to make a request message: %w", err) - } - - err = conn.SendMessage(requestMessage) - if err != nil { - if conn.metrics != nil { - conn.metrics.IncreaseCounterForRequestResponseFailures(1) - } - return xerrors.Errorf("failed to send a request message: %w", err) - } - - return nil -} - // RequestAndCheck sends a request and expects a CheckErrorResponse, on which the error is already checked. func (conn *IRODSConnection) RequestAndCheck(request Request, response CheckErrorResponse, bsBuffer []byte) error { return conn.RequestAndCheckWithTrackerCallBack(request, response, bsBuffer, nil, nil) @@ -281,39 +234,29 @@ func (conn *IRODSConnection) RequestAndCheckWithTrackerCallBack(request Request, return response.CheckError() } -// RequestAndCheckForPassword sends a request and expects a CheckErrorResponse, on which the error is already checked. -// Only escape '&' -func (conn *IRODSConnection) RequestAndCheckForPassword(request Request, response CheckErrorResponse, bsBuffer []byte) error { - if err := conn.RequestForPassword(request, response, bsBuffer); err != nil { - return err - } - - return response.CheckError() -} - -func (conn *IRODSConnection) getRequestMessage(request Request, xml bool, forPassword bool) (*message.IRODSMessage, error) { +func (conn *IRODSConnection) getRequestMessage(request Request) (*message.IRODSMessage, error) { requestMessage, err := request.GetMessage() if err != nil { return nil, xerrors.Errorf("failed to make a request message: %w", err) } - if xml { - // translate xml.Marshal XML into irods-understandable XML (among others, replace " by ") - err = conn.PreprocessMessage(requestMessage, forPassword) + xmlCorrector := request.GetXMLCorrector() + if xmlCorrector != nil { + err := xmlCorrector(requestMessage, conn.useNewXML()) if err != nil { - return nil, xerrors.Errorf("failed to send preprocess message: %w", err) + return nil, xerrors.Errorf("failed to corrext XML message: %w", err) } } return requestMessage, nil } -func (conn *IRODSConnection) getResponse(responseMessage *message.IRODSMessage, response Response, xml bool) error { - if xml { - // translate irods-dialect XML into valid XML - err := conn.PostprocessMessage(responseMessage) +func (conn *IRODSConnection) getResponse(responseMessage *message.IRODSMessage, response Response) error { + xmlCorrector := response.GetXMLCorrector() + if xmlCorrector != nil { + err := xmlCorrector(responseMessage, conn.useNewXML()) if err != nil { - return xerrors.Errorf("failed to postprocess message: %w", err) + return xerrors.Errorf("failed to corrext XML message: %w", err) } } diff --git a/irods/connection/resource_server_connection.go b/irods/connection/resource_server_connection.go index 2248fd5..d410c30 100644 --- a/irods/connection/resource_server_connection.go +++ b/irods/connection/resource_server_connection.go @@ -250,9 +250,11 @@ func (conn *IRODSResourceServerConnection) Disconnect() error { err := conn.disconnectNow() if err != nil { + logger.WithError(err).Debug("failed to disconnect the connection") return err } + logger.Debug("Disconnected the connection") return nil } diff --git a/irods/connection/xml.go b/irods/connection/xml.go deleted file mode 100644 index 27b5ed2..0000000 --- a/irods/connection/xml.go +++ /dev/null @@ -1,223 +0,0 @@ -package connection - -import ( - "bytes" - "strconv" - "strings" - "unicode/utf8" - - "github.com/cyverse/go-irodsclient/irods/message" - "golang.org/x/xerrors" -) - -var ( - // escapes from xml.Encode - escQuot = []byte(""") // shorter than """, \" - escApos = []byte("'") // shorter than "'", \' - escTab = []byte(" ") - escNL = []byte(" ") - escCR = []byte(" ") - escFFFD = []byte("\uFFFD") // Unicode replacement character - - // escapes for irods - irodsEscQuot = []byte(""") - irodsEscApos = []byte("'") -) - -// ErrInvalidUTF8 is returned if an invalid utf-8 character is found. -var ErrInvalidUTF8 = xerrors.Errorf("invalid utf-8 character") - -func (conn *IRODSConnection) talksCorrectXML() bool { - if conn.serverVersion == nil { - // We don't know the server version yet, assume the best - return true - } - - if !strings.HasPrefix(conn.serverVersion.ReleaseVersion, "rods") { - // Strange, but hopefully it talks correct xml - return true - } - - version := strings.Split(conn.serverVersion.ReleaseVersion[4:], ".") - - if len(version) != 3 { - // Strange, but hopefully it talks correct xml - return true - } - - major, _ := strconv.Atoi(version[0]) - minor, _ := strconv.Atoi(version[1]) - release, _ := strconv.Atoi(version[2]) - - return major > 4 || (major == 4 && minor > 2) || (major == 4 && minor == 2 && release > 8) -} - -// PostprocessMessage prepares a message that is received from irods for XML parsing. -func (conn *IRODSConnection) PostprocessMessage(msg *message.IRODSMessage) error { - if msg.Body == nil || msg.Body.Message == nil { - return nil - } - - var err error - - msg.Body.Message, err = conn.PostprocessXML(msg.Body.Message) - msg.Header.MessageLen = uint32(len(msg.Body.Message)) - - return err -} - -// PostprocessXML translates IRODS XML into valid XML. -// We fix the invalid encoding of ` as ". -func (conn *IRODSConnection) PostprocessXML(in []byte) ([]byte, error) { - buf := in - out := &bytes.Buffer{} - - for len(buf) > 0 { - switch { - // turn " into ` - case bytes.HasPrefix(buf, irodsEscQuot) && !conn.talksCorrectXML(): - out.WriteByte('`') - buf = buf[len(irodsEscQuot):] - // turn ' into ' - case buf[0] == '\'' && !conn.talksCorrectXML(): - out.Write(escApos) - buf = buf[1:] - // check utf8 characters for validity - default: - r, size := utf8.DecodeRune(buf) - if r == utf8.RuneError && size == 1 { - return in, ErrInvalidUTF8 - } - - if isValidChar(r) { - out.Write(buf[:size]) - } else { - out.Write(escFFFD) - } - - buf = buf[size:] - } - } - - return out.Bytes(), nil -} - -// PreprocessMessage modifies a request message to use irods dialect for XML. -func (conn *IRODSConnection) PreprocessMessage(msg *message.IRODSMessage, forPassword bool) error { - if msg.Body == nil || msg.Body.Message == nil { - return nil - } - - var err error - - if forPassword { - msg.Body.Message, err = conn.PreprocessXMLForPassword(msg.Body.Message) - } else { - msg.Body.Message, err = conn.PreprocessXML(msg.Body.Message) - } - - msg.Header.MessageLen = uint32(len(msg.Body.Message)) - - return err -} - -// PreprocessXML translates output of xml.Marshal into XML that IRODS understands. -func (conn *IRODSConnection) PreprocessXML(in []byte) ([]byte, error) { - buf := in - out := &bytes.Buffer{} - - for len(buf) > 0 { - switch { - // turn " into " - case bytes.HasPrefix(buf, escQuot): - out.Write(irodsEscQuot) - buf = buf[len(escQuot):] - // turn ' into ' or ' - case bytes.HasPrefix(buf, escApos): - if conn.talksCorrectXML() { - out.Write(irodsEscApos) - } else { - out.WriteByte('\'') - } - buf = buf[len(escApos):] - // irods does not decode encoded tabs - case bytes.HasPrefix(buf, escTab): - out.WriteByte('\t') - buf = buf[len(escTab):] - // irods does not decode encoded carriage returns - case bytes.HasPrefix(buf, escCR): - out.WriteByte('\r') - buf = buf[len(escCR):] - // irods does not decode encoded newlines - case bytes.HasPrefix(buf, escNL): - out.WriteByte('\n') - buf = buf[len(escNL):] - // turn ` into ' - case buf[0] == '`' && !conn.talksCorrectXML(): - out.Write(irodsEscApos) - buf = buf[1:] - // pass utf8 characters - default: - r, size := utf8.DecodeRune(buf) - if r == utf8.RuneError && size == 1 { - return in, ErrInvalidUTF8 - } - - out.Write(buf[:size]) - buf = buf[size:] - } - } - - return out.Bytes(), nil -} - -// PreprocessXMLForPassword translates output of xml.Marshal into XML that IRODS understands. -func (conn *IRODSConnection) PreprocessXMLForPassword(in []byte) ([]byte, error) { - buf := in - out := &bytes.Buffer{} - - for len(buf) > 0 { - switch { - // turn " into \" - case bytes.HasPrefix(buf, escQuot): - out.WriteByte('"') - buf = buf[len(escQuot):] - // turn ' into \' - case bytes.HasPrefix(buf, escApos): - out.WriteByte('\'') - buf = buf[len(escApos):] - // irods does not decode encoded tabs - case bytes.HasPrefix(buf, escTab): - out.WriteByte('\t') - buf = buf[len(escTab):] - // irods does not decode encoded carriage returns - case bytes.HasPrefix(buf, escCR): - out.WriteByte('\r') - buf = buf[len(escCR):] - // irods does not decode encoded newlines - case bytes.HasPrefix(buf, escNL): - out.WriteByte('\n') - buf = buf[len(escNL):] - // pass utf8 characters - default: - r, size := utf8.DecodeRune(buf) - if r == utf8.RuneError && size == 1 { - return in, ErrInvalidUTF8 - } - - out.Write(buf[:size]) - buf = buf[size:] - } - } - - return out.Bytes(), nil -} - -func isValidChar(r rune) bool { - return r == 0x09 || - r == 0x0A || - r == 0x0D || - r >= 0x20 && r <= 0xD7FF || - r >= 0xE000 && r <= 0xFFFD || - r >= 0x10000 && r <= 0x10FFFF -} diff --git a/irods/fs/data_object_resource_server.go b/irods/fs/data_object_resource_server.go index db4cdd9..7193f36 100644 --- a/irods/fs/data_object_resource_server.go +++ b/irods/fs/data_object_resource_server.go @@ -186,13 +186,13 @@ func CompleteDataObjectRedirection(conn *connection.IRODSConnection, handle *typ return nil } -func downloadDataObjectChunkFromResourceServer(sess *session.IRODSSession, controlConnection *connection.IRODSConnection, handle *types.IRODSFileOpenRedirectionHandle, localPath string, callback common.TrackerCallBack) error { +func downloadDataObjectChunkFromResourceServer(sess *session.IRODSSession, taskID int, controlConnection *connection.IRODSConnection, handle *types.IRODSFileOpenRedirectionHandle, localPath string, callback common.TrackerCallBack) error { logger := log.WithFields(log.Fields{ "package": "fs", "function": "downloadDataObjectChunkFromResourceServer", }) - logger.Debugf("download data object %s", handle.Path) + logger.Debugf("download data object %s, task %d", handle.Path, taskID) conn := sess.GetRedirectionConnection(controlConnection, handle.RedirectionInfo) err := conn.Connect() @@ -359,16 +359,18 @@ func downloadDataObjectChunkFromResourceServer(sess *session.IRODSSession, contr } } + logger.Debugf("downloaded data object %s, task %d", handle.Path, taskID) + return nil } -func uploadDataObjectChunkToResourceServer(sess *session.IRODSSession, controlConnection *connection.IRODSConnection, handle *types.IRODSFileOpenRedirectionHandle, localPath string, callback common.TrackerCallBack) error { +func uploadDataObjectChunkToResourceServer(sess *session.IRODSSession, taskID int, controlConnection *connection.IRODSConnection, handle *types.IRODSFileOpenRedirectionHandle, localPath string, callback common.TrackerCallBack) error { logger := log.WithFields(log.Fields{ "package": "fs", "function": "uploadDataObjectChunkToResourceServer", }) - logger.Debugf("upload data object %s", handle.Path) + logger.Debugf("upload data object %s, task %d", handle.Path, taskID) conn := sess.GetRedirectionConnection(controlConnection, handle.RedirectionInfo) err := conn.Connect() @@ -551,6 +553,8 @@ func uploadDataObjectChunkToResourceServer(sess *session.IRODSSession, controlCo } } + logger.Debugf("uploaded data object %s, task %d", handle.Path, taskID) + return nil } @@ -644,7 +648,7 @@ func DownloadDataObjectFromResourceServer(session *session.IRODSSession, irodsPa } } - err = downloadDataObjectChunkFromResourceServer(session, conn, handle, localPath, blockReadCallback) + err = downloadDataObjectChunkFromResourceServer(session, taskID, conn, handle, localPath, blockReadCallback) if err != nil { dnErr := xerrors.Errorf("failed to download data object chunk %q from resource server: %w", irodsPath, err) errChan <- dnErr @@ -758,7 +762,7 @@ func UploadDataObjectToResourceServer(session *session.IRODSSession, localPath s } } - err = uploadDataObjectChunkToResourceServer(session, conn, handle, localPath, blockWriteCallback) + err = uploadDataObjectChunkToResourceServer(session, taskID, conn, handle, localPath, blockWriteCallback) if err != nil { dnErr := xerrors.Errorf("failed to upload data object chunk %q to resource server: %w", localPath, err) errChan <- dnErr diff --git a/irods/fs/struct_file.go b/irods/fs/struct_file.go index 6fc5482..e1a8d86 100644 --- a/irods/fs/struct_file.go +++ b/irods/fs/struct_file.go @@ -32,7 +32,7 @@ func ExtractStructFile(conn *connection.IRODSConnection, path string, target str } request := message.NewIRODSMessageExtractStructFileRequest(path, target, resource, dataType, force, bulkReg) - response := message.IRODSMessageRemoveDataObjectResponse{} + response := message.IRODSMessageExtractStructFileResponse{} err := conn.RequestAndCheck(request, &response, nil) if err != nil { if types.GetIRODSErrorCode(err) == common.CAT_NO_ROWS_FOUND { diff --git a/irods/fs/ticket.go b/irods/fs/ticket.go index a1dc039..c0fc542 100644 --- a/irods/fs/ticket.go +++ b/irods/fs/ticket.go @@ -1248,7 +1248,7 @@ func CreateTicket(conn *connection.IRODSConnection, ticketName string, ticketTyp req := message.NewIRODSMessageTicketAdminRequest("create", ticketName, string(ticketType), path, ticketName) - err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageTicketAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received create ticket error: %w", err) } @@ -1263,7 +1263,7 @@ func DeleteTicket(conn *connection.IRODSConnection, ticketName string) error { req := message.NewIRODSMessageTicketAdminRequest("delete", ticketName) - err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageTicketAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received delete ticket error: %w", err) } @@ -1278,7 +1278,7 @@ func ModifyTicket(conn *connection.IRODSConnection, ticketName string, args ...s req := message.NewIRODSMessageTicketAdminRequest("mod", ticketName, args...) - err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageTicketAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received mod ticket error: %w", err) } @@ -1364,7 +1364,7 @@ func SupplyTicket(conn *connection.IRODSConnection, ticketName string) error { defer conn.Unlock() req := message.NewIRODSMessageTicketAdminRequest("session", ticketName) - err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageTicketAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received supply ticket error: %w", err) } diff --git a/irods/fs/usergroup.go b/irods/fs/usergroup.go index 198727b..221f9ef 100644 --- a/irods/fs/usergroup.go +++ b/irods/fs/usergroup.go @@ -508,15 +508,15 @@ func ChangeUserPassword(conn *connection.IRODSConnection, username string, zone account := conn.GetAccount() oldPassword := account.Password - if account.AuthenticationScheme == types.AuthSchemePAM { + if account.AuthenticationScheme.IsPAM() { oldPassword = conn.GetPAMToken() } scrambledPassword := util.ObfuscateNewPassword(newPassword, oldPassword, conn.GetClientSignature()) - req := message.NewIRODSMessageAdminRequest("modify", "user", userZoneName, "password", scrambledPassword, zone) + req := message.NewIRODSMessageAdminChangePasswordRequest(userZoneName, scrambledPassword, zone) - err := conn.RequestAndCheckForPassword(req, &message.IRODSMessageAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received change user password error: %w", err) } @@ -563,7 +563,7 @@ func CreateGroup(conn *connection.IRODSConnection, groupname string, groupType s req := message.NewIRODSMessageAdminRequest("add", "user", groupname, groupType) - err := conn.RequestAndCheck(req, &message.IRODSMessageUserAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received create group error: %w", err) } @@ -578,7 +578,7 @@ func AddGroupMember(conn *connection.IRODSConnection, groupname string, username req := message.NewIRODSMessageAdminRequest("modify", "group", groupname, "add", username, zone) - err := conn.RequestAndCheck(req, &message.IRODSMessageUserAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received add group member error: %w", err) } @@ -593,7 +593,7 @@ func RemoveGroupMember(conn *connection.IRODSConnection, groupname string, usern req := message.NewIRODSMessageAdminRequest("modify", "group", groupname, "remove", username, zone) - err := conn.RequestAndCheck(req, &message.IRODSMessageUserAdminResponse{}, nil) + err := conn.RequestAndCheck(req, &message.IRODSMessageAdminResponse{}, nil) if err != nil { return xerrors.Errorf("received remove group member error: %w", err) } diff --git a/irods/message/admin_change_password_request.go b/irods/message/admin_change_password_request.go new file mode 100644 index 0000000..475b49a --- /dev/null +++ b/irods/message/admin_change_password_request.go @@ -0,0 +1,87 @@ +package message + +import ( + "encoding/xml" + + "github.com/cyverse/go-irodsclient/irods/common" + "golang.org/x/xerrors" +) + +// IRODSMessageAdminRequestIRODSMessageAdminChangePasswordRequest stores change password request +type IRODSMessageAdminChangePasswordRequest struct { + XMLName xml.Name `xml:"generalAdminInp_PI"` + Action string `xml:"arg0"` // add, modify, rm, ... + Target string `xml:"arg1"` // user, group, zone, resource, ... + Arg2 string `xml:"arg2"` + Arg3 string `xml:"arg3"` + Arg4 string `xml:"arg4"` + Arg5 string `xml:"arg5"` + Arg6 string `xml:"arg6"` + Arg7 string `xml:"arg7"` + Arg8 string `xml:"arg8"` // unused + Arg9 string `xml:"arg9"` // unused +} + +// NewIRODSMessageAdminChangePasswordRequest creates a new IRODSMessageAdminChangePasswordRequest +func NewIRODSMessageAdminChangePasswordRequest(username string, password string, zone string) *IRODSMessageAdminChangePasswordRequest { + request := &IRODSMessageAdminChangePasswordRequest{ + Action: "modify", + Target: "user", + } + + request.Arg2 = username // zone name + request.Arg3 = "password" + request.Arg4 = password // password + request.Arg5 = zone + + return request +} + +// GetBytes returns byte array +func (msg *IRODSMessageAdminChangePasswordRequest) GetBytes() ([]byte, error) { + xmlBytes, err := xml.Marshal(msg) + if err != nil { + return nil, xerrors.Errorf("failed to marshal irods message to xml: %w", err) + } + return xmlBytes, nil +} + +// FromBytes returns struct from bytes +func (msg *IRODSMessageAdminChangePasswordRequest) FromBytes(bytes []byte) error { + err := xml.Unmarshal(bytes, msg) + if err != nil { + return xerrors.Errorf("failed to unmarshal xml to irods message: %w", err) + } + return nil +} + +// GetMessage builds a message +func (msg *IRODSMessageAdminChangePasswordRequest) GetMessage() (*IRODSMessage, error) { + bytes, err := msg.GetBytes() + if err != nil { + return nil, xerrors.Errorf("failed to get bytes from irods message: %w", err) + } + + msgBody := IRODSMessageBody{ + Type: RODS_MESSAGE_API_REQ_TYPE, + Message: bytes, + Error: nil, + Bs: nil, + IntInfo: int32(common.GENERAL_ADMIN_AN), + } + + msgHeader, err := msgBody.BuildHeader() + if err != nil { + return nil, xerrors.Errorf("failed to build header from irods message: %w", err) + } + + return &IRODSMessage{ + Header: msgHeader, + Body: &msgBody, + }, nil +} + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAdminChangePasswordRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForPasswordRequest() +} diff --git a/irods/message/admin_request.go b/irods/message/admin_request.go index 378f598..0d6fe13 100644 --- a/irods/message/admin_request.go +++ b/irods/message/admin_request.go @@ -107,3 +107,8 @@ func (msg *IRODSMessageAdminRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAdminRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/admin_response.go b/irods/message/admin_response.go index 00b8aa1..65b3b58 100644 --- a/irods/message/admin_response.go +++ b/irods/message/admin_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageAdminResponse) FromMessage(msgIn *IRODSMessage) error { msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAdminResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/auth_challenge_response.go b/irods/message/auth_challenge_response.go index 3896dd6..6cacb51 100644 --- a/irods/message/auth_challenge_response.go +++ b/irods/message/auth_challenge_response.go @@ -5,6 +5,7 @@ import ( "encoding/xml" "github.com/cyverse/go-irodsclient/irods/common" + "github.com/cyverse/go-irodsclient/irods/types" "golang.org/x/xerrors" ) @@ -12,6 +13,16 @@ import ( type IRODSMessageAuthChallengeResponse struct { XMLName xml.Name `xml:"authRequestOut_PI"` Challenge string `xml:"challenge"` + // stores error return + Result int `xml:"-"` +} + +// CheckError returns error if server returned an error +func (msg *IRODSMessageAuthChallengeResponse) CheckError() error { + if msg.Result < 0 { + return types.NewIRODSError(common.ErrorCode(msg.Result)) + } + return nil } // GetBytes returns byte array @@ -64,13 +75,23 @@ func (msg *IRODSMessageAuthChallengeResponse) FromMessage(msgIn *IRODSMessage) e return xerrors.Errorf("empty message body") } - err := msg.FromBytes(msgIn.Body.Message) - if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + msg.Result = int(msgIn.Body.IntInfo) + + if msgIn.Body.Message != nil { + err := msg.FromBytes(msgIn.Body.Message) + if err != nil { + return xerrors.Errorf("failed to get irods message from message body: %w", err) + } } + return nil } +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAuthChallengeResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} + // GetChallenge returns challenge bytes func (msg *IRODSMessageAuthChallengeResponse) GetChallenge() ([]byte, error) { challengeBytes, err := base64.StdEncoding.DecodeString(msg.Challenge) diff --git a/irods/message/auth_pam_request.go b/irods/message/auth_pam_request.go index a1166e0..72804dc 100644 --- a/irods/message/auth_pam_request.go +++ b/irods/message/auth_pam_request.go @@ -67,3 +67,8 @@ func (msg *IRODSMessagePamAuthRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessagePamAuthRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/auth_pam_response.go b/irods/message/auth_pam_response.go index 0015772..eef3109 100644 --- a/irods/message/auth_pam_response.go +++ b/irods/message/auth_pam_response.go @@ -3,6 +3,8 @@ package message import ( "encoding/xml" + "github.com/cyverse/go-irodsclient/irods/common" + "github.com/cyverse/go-irodsclient/irods/types" "golang.org/x/xerrors" ) @@ -10,6 +12,16 @@ import ( type IRODSMessagePamAuthResponse struct { XMLName xml.Name `xml:"pamAuthRequestOut_PI"` GeneratedPassword string `xml:"irodsPamPassword"` + // stores error return + Result int `xml:"-"` +} + +// CheckError returns error if server returned an error +func (msg *IRODSMessagePamAuthResponse) CheckError() error { + if msg.Result < 0 { + return types.NewIRODSError(common.ErrorCode(msg.Result)) + } + return nil } // GetBytes returns byte array @@ -36,9 +48,19 @@ func (msg *IRODSMessagePamAuthResponse) FromMessage(msgIn *IRODSMessage) error { return xerrors.Errorf("empty message body") } - err := msg.FromBytes(msgIn.Body.Message) - if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + msg.Result = int(msgIn.Body.IntInfo) + + if msgIn.Body.Message != nil { + err := msg.FromBytes(msgIn.Body.Message) + if err != nil { + return xerrors.Errorf("failed to get irods message from message body: %w", err) + } } + return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessagePamAuthResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/auth_plugin_request.go b/irods/message/auth_plugin_request.go index 33e6861..44f71da 100644 --- a/irods/message/auth_plugin_request.go +++ b/irods/message/auth_plugin_request.go @@ -65,3 +65,8 @@ func (msg *IRODSMessageAuthPluginRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAuthPluginRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/auth_plugin_response.go b/irods/message/auth_plugin_response.go index de56deb..c5ba897 100644 --- a/irods/message/auth_plugin_response.go +++ b/irods/message/auth_plugin_response.go @@ -3,13 +3,25 @@ package message import ( "encoding/xml" + "github.com/cyverse/go-irodsclient/irods/common" + "github.com/cyverse/go-irodsclient/irods/types" "golang.org/x/xerrors" ) // IRODSMessageAuthPluginResponse stores auth plugin info type IRODSMessageAuthPluginResponse struct { - XMLName xml.Name `xml:"authPlugReqOut_PI"` - Result string `xml:"result_"` + XMLName xml.Name `xml:"authPlugReqOut_PI"` + GeneratedPassword []byte `xml:"result_"` + // stores error return + Result int `xml:"-"` +} + +// CheckError returns error if server returned an error +func (msg *IRODSMessageAuthPluginResponse) CheckError() error { + if msg.Result < 0 { + return types.NewIRODSError(common.ErrorCode(msg.Result)) + } + return nil } // GetBytes returns byte array @@ -22,11 +34,12 @@ func (msg *IRODSMessageAuthPluginResponse) GetBytes() ([]byte, error) { } // FromBytes returns struct from bytes -func (msg *IRODSMessageAuthPluginResponse) FromBytes(bytes []byte) error { - err := xml.Unmarshal(bytes, msg) +func (msg *IRODSMessageAuthPluginResponse) FromBytes(b []byte) error { + err := xml.Unmarshal(b, msg) if err != nil { return xerrors.Errorf("failed to unmarshal xml to irods message: %w", err) } + return nil } @@ -36,9 +49,19 @@ func (msg *IRODSMessageAuthPluginResponse) FromMessage(msgIn *IRODSMessage) erro return xerrors.Errorf("empty message body") } - err := msg.FromBytes(msgIn.Body.Message) - if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + msg.Result = int(msgIn.Body.IntInfo) + + if msgIn.Body.Message != nil { + err := msg.FromBytes(msgIn.Body.Message) + if err != nil { + return xerrors.Errorf("failed to get irods message from message body: %w", err) + } } + return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAuthPluginResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForPasswordResponse() +} diff --git a/irods/message/auth_request.go b/irods/message/auth_request.go index cf760ff..1343c6b 100644 --- a/irods/message/auth_request.go +++ b/irods/message/auth_request.go @@ -34,3 +34,7 @@ func (msg *IRODSMessageAuthRequest) GetMessage() (*IRODSMessage, error) { func (msg *IRODSMessageAuthRequest) FromMessage(msgIn *IRODSMessage) error { return nil } + +func (msg *IRODSMessageAuthRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/auth_response.go b/irods/message/auth_response.go index 77d6e51..ab9d86a 100644 --- a/irods/message/auth_response.go +++ b/irods/message/auth_response.go @@ -4,6 +4,7 @@ import ( "encoding/xml" "github.com/cyverse/go-irodsclient/irods/common" + "github.com/cyverse/go-irodsclient/irods/types" "golang.org/x/xerrors" ) @@ -12,6 +13,8 @@ type IRODSMessageAuthResponse struct { XMLName xml.Name `xml:"authResponseInp_PI"` Response string `xml:"response"` Username string `xml:"username"` + // stores error return + Result int `xml:"-"` } // NewIRODSMessageAuthResponse creates a IRODSMessageAuthResponse message @@ -22,6 +25,14 @@ func NewIRODSMessageAuthResponse(response string, username string) *IRODSMessage } } +// CheckError returns error if server returned an error +func (msg *IRODSMessageAuthResponse) CheckError() error { + if msg.Result < 0 { + return types.NewIRODSError(common.ErrorCode(msg.Result)) + } + return nil +} + // GetBytes returns byte array func (msg *IRODSMessageAuthResponse) GetBytes() ([]byte, error) { xmlBytes, err := xml.Marshal(msg) @@ -72,9 +83,18 @@ func (msg *IRODSMessageAuthResponse) FromMessage(msgIn *IRODSMessage) error { return xerrors.Errorf("empty message body") } - err := msg.FromBytes(msgIn.Body.Message) - if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + msg.Result = int(msgIn.Body.IntInfo) + + if msgIn.Body.Message != nil { + err := msg.FromBytes(msgIn.Body.Message) + if err != nil { + return xerrors.Errorf("failed to get irods message from message body: %w", err) + } } + return nil } + +func (msg *IRODSMessageAuthResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/auth_result.go b/irods/message/auth_result.go index 8a58bdd..4e38ec9 100644 --- a/irods/message/auth_result.go +++ b/irods/message/auth_result.go @@ -45,3 +45,8 @@ func (msg *IRODSMessageAuthResult) FromMessage(msgIn *IRODSMessage) error { msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageAuthResult) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/checksum_request.go b/irods/message/checksum_request.go index b47e068..1439725 100644 --- a/irods/message/checksum_request.go +++ b/irods/message/checksum_request.go @@ -84,3 +84,8 @@ func (msg *IRODSMessageChecksumRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageChecksumRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/checksum_response.go b/irods/message/checksum_response.go index b9d5996..f74b698 100644 --- a/irods/message/checksum_response.go +++ b/irods/message/checksum_response.go @@ -60,9 +60,14 @@ func (msg *IRODSMessageChecksumResponse) FromMessage(msgIn *IRODSMessage) error if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageChecksumResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/close_data_object_replica_request.go b/irods/message/close_data_object_replica_request.go index 39d3913..487abb6 100644 --- a/irods/message/close_data_object_replica_request.go +++ b/irods/message/close_data_object_replica_request.go @@ -101,3 +101,8 @@ func (msg *IRODSMessageCloseDataObjectReplicaRequest) GetMessage() (*IRODSMessag Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCloseDataObjectReplicaRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/close_data_object_replica_response.go b/irods/message/close_data_object_replica_response.go index 531360a..ccbaeb8 100644 --- a/irods/message/close_data_object_replica_response.go +++ b/irods/message/close_data_object_replica_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageCloseDataObjectReplicaResponse) FromMessage(msgIn *IRODSM msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCloseDataObjectReplicaResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/close_data_object_request.go b/irods/message/close_data_object_request.go index e70f8ba..0418759 100644 --- a/irods/message/close_data_object_request.go +++ b/irods/message/close_data_object_request.go @@ -75,3 +75,8 @@ func (msg *IRODSMessageCloseDataObjectRequest) GetMessage() (*IRODSMessage, erro Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCloseDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/close_data_object_response.go b/irods/message/close_data_object_response.go index e3236d5..39294cf 100644 --- a/irods/message/close_data_object_response.go +++ b/irods/message/close_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageCloseDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCloseDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/copy_data_object_request.go b/irods/message/copy_data_object_request.go index 88f4dff..3e6cd1e 100644 --- a/irods/message/copy_data_object_request.go +++ b/irods/message/copy_data_object_request.go @@ -101,3 +101,8 @@ func (msg *IRODSMessageCopyDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCopyDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/copy_data_object_response.go b/irods/message/copy_data_object_response.go index 55e1bbc..3b95611 100644 --- a/irods/message/copy_data_object_response.go +++ b/irods/message/copy_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageCopyDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCopyDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/create_data_object_request.go b/irods/message/create_data_object_request.go index 9846d68..21c3237 100644 --- a/irods/message/create_data_object_request.go +++ b/irods/message/create_data_object_request.go @@ -124,3 +124,8 @@ func (msg *IRODSMessageCreateDataObjectRequest) GetMessage() (*IRODSMessage, err Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCreateDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/create_data_object_response.go b/irods/message/create_data_object_response.go index 32eb769..f440238 100644 --- a/irods/message/create_data_object_response.go +++ b/irods/message/create_data_object_response.go @@ -34,3 +34,8 @@ func (msg *IRODSMessageCreateDataObjectResponse) FromMessage(msgIn *IRODSMessage msg.FileDescriptor = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageCreateDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/cs_negotiation.go b/irods/message/cs_negotiation.go index 99edc4a..dc1c6a4 100644 --- a/irods/message/cs_negotiation.go +++ b/irods/message/cs_negotiation.go @@ -100,7 +100,11 @@ func (msg *IRODSMessageCSNegotiation) FromMessage(msgIn *IRODSMessage) error { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } return nil } + +func (msg *IRODSMessageCSNegotiation) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/disconnect.go b/irods/message/disconnect.go index c885bde..5f9c631 100644 --- a/irods/message/disconnect.go +++ b/irods/message/disconnect.go @@ -35,3 +35,8 @@ func (msg *IRODSMessageDisconnect) GetMessage() (*IRODSMessage, error) { func (msg *IRODSMessageDisconnect) FromMessage(msgIn *IRODSMessage) error { return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageDisconnect) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/end_transaction_request.go b/irods/message/end_transaction_request.go index 6dfb290..deda534 100644 --- a/irods/message/end_transaction_request.go +++ b/irods/message/end_transaction_request.go @@ -72,3 +72,8 @@ func (msg *IRODSMessageEndTransactionRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageEndTransactionRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/end_transaction_response.go b/irods/message/end_transaction_response.go index db96fae..29d9d80 100644 --- a/irods/message/end_transaction_response.go +++ b/irods/message/end_transaction_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageEndTransactionResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageEndTransactionResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/error.go b/irods/message/error.go index 972a1ec..401255d 100644 --- a/irods/message/error.go +++ b/irods/message/error.go @@ -96,7 +96,7 @@ func (msg *IRODSMessageError) FromMessage(msgIn *IRODSMessage) error { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } return nil } diff --git a/irods/message/extract_struct_file_request.go b/irods/message/extract_struct_file_request.go index f499ddd..43bf8d4 100644 --- a/irods/message/extract_struct_file_request.go +++ b/irods/message/extract_struct_file_request.go @@ -97,3 +97,8 @@ func (msg *IRODSMessageExtractStructFileRequest) GetMessage() (*IRODSMessage, er Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageExtractStructFileRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/extract_struct_file_response.go b/irods/message/extract_struct_file_response.go index a924881..c315a61 100644 --- a/irods/message/extract_struct_file_response.go +++ b/irods/message/extract_struct_file_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageExtractStructFileResponse) FromMessage(msgIn *IRODSMessag msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageExtractStructFileResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/get_data_object_complete_request.go b/irods/message/get_data_object_complete_request.go index 9f3bbad..b923ef5 100644 --- a/irods/message/get_data_object_complete_request.go +++ b/irods/message/get_data_object_complete_request.go @@ -62,3 +62,8 @@ func (msg *IRODSMessageGetDataObjectCompleteRequest) GetMessage() (*IRODSMessage Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDataObjectCompleteRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/get_data_object_complete_response.go b/irods/message/get_data_object_complete_response.go index 6b64be5..32c865d 100644 --- a/irods/message/get_data_object_complete_response.go +++ b/irods/message/get_data_object_complete_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageGetDataObjectCompleteResponse) FromMessage(msgIn *IRODSMe msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDataObjectCompleteResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/get_data_object_request.go b/irods/message/get_data_object_request.go index 7c2c130..4372485 100644 --- a/irods/message/get_data_object_request.go +++ b/irods/message/get_data_object_request.go @@ -80,3 +80,8 @@ func (msg *IRODSMessageGetDataObjectRequest) GetMessage() (*IRODSMessage, error) Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/get_data_object_response.go b/irods/message/get_data_object_response.go index 1820cec..d5b6263 100644 --- a/irods/message/get_data_object_response.go +++ b/irods/message/get_data_object_response.go @@ -48,9 +48,14 @@ func (msg *IRODSMessageGetDataObjectResponse) FromMessage(msgIn *IRODSMessage) e if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/get_data_object_stat_request.go b/irods/message/get_data_object_stat_request.go index 0e2218a..d590b65 100644 --- a/irods/message/get_data_object_stat_request.go +++ b/irods/message/get_data_object_stat_request.go @@ -53,3 +53,8 @@ func (msg *IRODSMessageGetDataObjectStatRequest) GetMessage() (*IRODSMessage, er Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDataObjectStatRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/get_data_object_stat_response.go b/irods/message/get_data_object_stat_response.go index 50ec6e5..7de483a 100644 --- a/irods/message/get_data_object_stat_response.go +++ b/irods/message/get_data_object_stat_response.go @@ -62,9 +62,14 @@ func (msg *IRODSMessageGetDataObjectStatResponse) FromMessage(msgIn *IRODSMessag if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDataObjectStatResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/get_descriptor_info_request.go b/irods/message/get_descriptor_info_request.go index a15f650..4ce8cfd 100644 --- a/irods/message/get_descriptor_info_request.go +++ b/irods/message/get_descriptor_info_request.go @@ -87,3 +87,8 @@ func (msg *IRODSMessageGetDescriptorInfoRequest) GetMessage() (*IRODSMessage, er Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDescriptorInfoRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/get_descriptor_info_response.go b/irods/message/get_descriptor_info_response.go index a4e599b..cf6bbda 100644 --- a/irods/message/get_descriptor_info_response.go +++ b/irods/message/get_descriptor_info_response.go @@ -91,9 +91,14 @@ func (msg *IRODSMessageGetDescriptorInfoResponse) FromMessage(msgIn *IRODSMessag if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetDescriptorInfoResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/get_file_stat_request.go b/irods/message/get_file_stat_request.go index 25f550f..339658d 100644 --- a/irods/message/get_file_stat_request.go +++ b/irods/message/get_file_stat_request.go @@ -83,3 +83,8 @@ func (msg *IRODSMessageGetFileStatRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetFileStatRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/get_file_stat_response.go b/irods/message/get_file_stat_response.go index f3bd90e..629bba0 100644 --- a/irods/message/get_file_stat_response.go +++ b/irods/message/get_file_stat_response.go @@ -66,9 +66,14 @@ func (msg *IRODSMessageGetFileStatResponse) FromMessage(msgIn *IRODSMessage) err if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetFileStatResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/get_process_stat_request.go b/irods/message/get_process_stat_request.go index 8dd6a75..36e742b 100644 --- a/irods/message/get_process_stat_request.go +++ b/irods/message/get_process_stat_request.go @@ -76,3 +76,8 @@ func (msg *IRODSMessageGetProcessstatRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageGetProcessstatRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/lock_data_object_request.go b/irods/message/lock_data_object_request.go index 85a276e..564df1d 100644 --- a/irods/message/lock_data_object_request.go +++ b/irods/message/lock_data_object_request.go @@ -127,3 +127,8 @@ func (msg *IRODSMessageLockDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageLockDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/lock_data_object_response.go b/irods/message/lock_data_object_response.go index 072d4f1..e32e985 100644 --- a/irods/message/lock_data_object_response.go +++ b/irods/message/lock_data_object_response.go @@ -34,3 +34,8 @@ func (msg *IRODSMessageLockDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.FileDescriptor = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageLockDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/make_collection_request.go b/irods/message/make_collection_request.go index 782366b..a87d3c3 100644 --- a/irods/message/make_collection_request.go +++ b/irods/message/make_collection_request.go @@ -81,3 +81,8 @@ func (msg *IRODSMessageMakeCollectionRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageMakeCollectionRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/make_collection_response.go b/irods/message/make_collection_response.go index 2b63ab1..9e1e9bf 100644 --- a/irods/message/make_collection_response.go +++ b/irods/message/make_collection_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageMakeCollectionResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageMakeCollectionResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/modify_access_request.go b/irods/message/modify_access_request.go index 4ed8526..27dfc86 100644 --- a/irods/message/modify_access_request.go +++ b/irods/message/modify_access_request.go @@ -78,3 +78,8 @@ func (msg *IRODSMessageModifyAccessRequest) GetMessage() (*IRODSMessage, error) Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageModifyAccessRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/modify_access_response.go b/irods/message/modify_access_response.go index 1481a9d..89d1038 100644 --- a/irods/message/modify_access_response.go +++ b/irods/message/modify_access_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageModifyAccessResponse) FromMessage(msgIn *IRODSMessage) er msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageModifyAccessResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/modify_collection_request.go b/irods/message/modify_collection_request.go index 6b57fa2..3506827 100644 --- a/irods/message/modify_collection_request.go +++ b/irods/message/modify_collection_request.go @@ -72,3 +72,8 @@ func (msg *IRODSMessageModifyCollectionRequest) GetMessage() (*IRODSMessage, err Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageModifyCollectionRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/modify_collection_response.go b/irods/message/modify_collection_response.go index f123464..2464899 100644 --- a/irods/message/modify_collection_response.go +++ b/irods/message/modify_collection_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageModifyCollectionResponse) FromMessage(msgIn *IRODSMessage msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageModifyCollectionResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/modify_metadata_request.go b/irods/message/modify_metadata_request.go index 4ca687e..c630f78 100644 --- a/irods/message/modify_metadata_request.go +++ b/irods/message/modify_metadata_request.go @@ -175,3 +175,8 @@ func (msg *IRODSMessageModifyMetadataRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageModifyMetadataRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/modify_metadata_response.go b/irods/message/modify_metadata_response.go index 318eb04..22ec3bb 100644 --- a/irods/message/modify_metadata_response.go +++ b/irods/message/modify_metadata_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageModifyMetadataResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageModifyMetadataResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/move_collection_request.go b/irods/message/move_collection_request.go index 0b063dc..e39529b 100644 --- a/irods/message/move_collection_request.go +++ b/irods/message/move_collection_request.go @@ -88,3 +88,8 @@ func (msg *IRODSMessageMoveCollectionRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageMoveCollectionRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/move_collection_response.go b/irods/message/move_collection_response.go index 5bce407..1f5a82e 100644 --- a/irods/message/move_collection_response.go +++ b/irods/message/move_collection_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageMoveCollectionResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageMoveCollectionResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/move_data_object_request.go b/irods/message/move_data_object_request.go index 76e4e08..e714a6c 100644 --- a/irods/message/move_data_object_request.go +++ b/irods/message/move_data_object_request.go @@ -88,3 +88,8 @@ func (msg *IRODSMessageMoveDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageMoveDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/move_data_object_response.go b/irods/message/move_data_object_response.go index d85900d..551ae3a 100644 --- a/irods/message/move_data_object_response.go +++ b/irods/message/move_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageMoveDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageMoveDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/open_data_object_request.go b/irods/message/open_data_object_request.go index 6a94b4b..9776ea1 100644 --- a/irods/message/open_data_object_request.go +++ b/irods/message/open_data_object_request.go @@ -157,3 +157,8 @@ func (msg *IRODSMessageOpenDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageOpenDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/open_data_object_response.go b/irods/message/open_data_object_response.go index f0e82bc..5e4c22f 100644 --- a/irods/message/open_data_object_response.go +++ b/irods/message/open_data_object_response.go @@ -34,3 +34,8 @@ func (msg *IRODSMessageOpenDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.FileDescriptor = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageOpenDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/operation_complete_request.go b/irods/message/operation_complete_request.go index b687167..ebc5c9a 100644 --- a/irods/message/operation_complete_request.go +++ b/irods/message/operation_complete_request.go @@ -62,3 +62,8 @@ func (msg *IRODSMessageOperationCompleteRequest) GetMessage() (*IRODSMessage, er Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageOperationCompleteRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/operation_complete_response.go b/irods/message/operation_complete_response.go index 5c6a1e8..2172c84 100644 --- a/irods/message/operation_complete_response.go +++ b/irods/message/operation_complete_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageOperationCompleteResponse) FromMessage(msgIn *IRODSMessag msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageOperationCompleteResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/put_data_object_request.go b/irods/message/put_data_object_request.go index 0d99ea5..b8bc89f 100644 --- a/irods/message/put_data_object_request.go +++ b/irods/message/put_data_object_request.go @@ -80,3 +80,8 @@ func (msg *IRODSMessagePutDataObjectRequest) GetMessage() (*IRODSMessage, error) Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessagePutDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/put_data_object_response.go b/irods/message/put_data_object_response.go index 5efae8f..d40080b 100644 --- a/irods/message/put_data_object_response.go +++ b/irods/message/put_data_object_response.go @@ -48,9 +48,14 @@ func (msg *IRODSMessagePutDataObjectResponse) FromMessage(msgIn *IRODSMessage) e if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessagePutDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/query_request.go b/irods/message/query_request.go index 2ce911a..aa6f838 100644 --- a/irods/message/query_request.go +++ b/irods/message/query_request.go @@ -99,3 +99,8 @@ func (msg *IRODSMessageQueryRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageQueryRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/query_response.go b/irods/message/query_response.go index 042f62c..6875996 100644 --- a/irods/message/query_response.go +++ b/irods/message/query_response.go @@ -58,9 +58,14 @@ func (msg *IRODSMessageQueryResponse) FromMessage(msgIn *IRODSMessage) error { if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageQueryResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/query_special_collection.go b/irods/message/query_special_collection.go index 6646812..203653c 100644 --- a/irods/message/query_special_collection.go +++ b/irods/message/query_special_collection.go @@ -61,7 +61,12 @@ func (msg *IRODSMessageQuerySpecialCollection) FromMessage(msgIn *IRODSMessage) err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageQuerySpecialCollection) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/query_specific_request.go b/irods/message/query_specific_request.go index 270e4b3..1cb08af 100644 --- a/irods/message/query_specific_request.go +++ b/irods/message/query_specific_request.go @@ -100,3 +100,8 @@ func (msg *IRODSMessageQuerySpecificRequest) GetMessage() (*IRODSMessage, error) Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageQuerySpecificRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/read_data_object_request.go b/irods/message/read_data_object_request.go index 3dc9902..0a7cc85 100644 --- a/irods/message/read_data_object_request.go +++ b/irods/message/read_data_object_request.go @@ -75,3 +75,8 @@ func (msg *IRODSMessageReadDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageReadDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/read_data_object_response.go b/irods/message/read_data_object_response.go index fc4aad1..b35d917 100644 --- a/irods/message/read_data_object_response.go +++ b/irods/message/read_data_object_response.go @@ -31,3 +31,8 @@ func (msg *IRODSMessageReadDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.Data = msgIn.Body.Bs return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageReadDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/remove_collection_request.go b/irods/message/remove_collection_request.go index 996dc9a..17f30f2 100644 --- a/irods/message/remove_collection_request.go +++ b/irods/message/remove_collection_request.go @@ -86,3 +86,8 @@ func (msg *IRODSMessageRemoveCollectionRequest) GetMessage() (*IRODSMessage, err Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageRemoveCollectionRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/remove_collection_response.go b/irods/message/remove_collection_response.go index 2995cce..40fb5c2 100644 --- a/irods/message/remove_collection_response.go +++ b/irods/message/remove_collection_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageRemoveCollectionResponse) FromMessage(msgIn *IRODSMessage msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageRemoveCollectionResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/remove_data_object_request.go b/irods/message/remove_data_object_request.go index 28b34cb..0bbf32c 100644 --- a/irods/message/remove_data_object_request.go +++ b/irods/message/remove_data_object_request.go @@ -80,3 +80,8 @@ func (msg *IRODSMessageRemoveDataObjectRequest) GetMessage() (*IRODSMessage, err Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageRemoveDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/remove_data_object_response.go b/irods/message/remove_data_object_response.go index a47870f..13db207 100644 --- a/irods/message/remove_data_object_response.go +++ b/irods/message/remove_data_object_response.go @@ -28,3 +28,8 @@ func (msg *IRODSMessageRemoveDataObjectResponse) FromMessage(msgIn *IRODSMessage msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageRemoveDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/replicate_data_object_request.go b/irods/message/replicate_data_object_request.go index 97f8b64..b6884f0 100644 --- a/irods/message/replicate_data_object_request.go +++ b/irods/message/replicate_data_object_request.go @@ -80,3 +80,8 @@ func (msg *IRODSMessageReplicateDataObjectRequest) GetMessage() (*IRODSMessage, Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageReplicateDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/replicate_data_object_response.go b/irods/message/replicate_data_object_response.go index 21a1eb1..69acc4d 100644 --- a/irods/message/replicate_data_object_response.go +++ b/irods/message/replicate_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageReplicateDataObjectResponse) FromMessage(msgIn *IRODSMess msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageReplicateDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/seek_data_object_request.go b/irods/message/seek_data_object_request.go index 18d096b..c1f7db1 100644 --- a/irods/message/seek_data_object_request.go +++ b/irods/message/seek_data_object_request.go @@ -76,3 +76,8 @@ func (msg *IRODSMessageSeekDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageSeekDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/seek_data_object_response.go b/irods/message/seek_data_object_response.go index 99def92..3b41c7c 100644 --- a/irods/message/seek_data_object_response.go +++ b/irods/message/seek_data_object_response.go @@ -40,9 +40,14 @@ func (msg *IRODSMessageSeekDataObjectResponse) FromMessage(msgIn *IRODSMessage) if msgIn.Body.Message != nil { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } } return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageSeekDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/ssl_settings.go b/irods/message/ssl_settings.go index 05f6ef9..0a6d552 100644 --- a/irods/message/ssl_settings.go +++ b/irods/message/ssl_settings.go @@ -71,3 +71,7 @@ func (msg *IRODSMessageSSLSettings) FromMessage(msgIn *IRODSMessage) error { return nil } + +func (msg *IRODSMessageSSLSettings) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/ssl_sharedsecret.go b/irods/message/ssl_sharedsecret.go index 49f8fc8..553ca97 100644 --- a/irods/message/ssl_sharedsecret.go +++ b/irods/message/ssl_sharedsecret.go @@ -52,3 +52,7 @@ func (msg *IRODSMessageSSLSharedSecret) FromMessage(msgIn *IRODSMessage) error { return nil } + +func (msg *IRODSMessageSSLSharedSecret) GetXMLCorrector() XMLCorrector { + return nil +} diff --git a/irods/message/startup_pack.go b/irods/message/startup_pack.go index 7d56f1a..d4f1f31 100644 --- a/irods/message/startup_pack.go +++ b/irods/message/startup_pack.go @@ -105,7 +105,11 @@ func (msg *IRODSMessageStartupPack) FromMessage(msgIn *IRODSMessage) error { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } return nil } + +func (msg *IRODSMessageStartupPack) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/ticket_admin_request.go b/irods/message/ticket_admin_request.go index 4a5373d..160058c 100644 --- a/irods/message/ticket_admin_request.go +++ b/irods/message/ticket_admin_request.go @@ -96,3 +96,7 @@ func (msg *IRODSMessageTicketAdminRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +func (msg *IRODSMessageTicketAdminRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/ticket_admin_response.go b/irods/message/ticket_admin_response.go index e0b45fe..e2831b3 100644 --- a/irods/message/ticket_admin_response.go +++ b/irods/message/ticket_admin_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageTicketAdminResponse) FromMessage(msgIn *IRODSMessage) err msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTicketAdminResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/touch_request.go b/irods/message/touch_request.go index 0e4554f..e06bcbe 100644 --- a/irods/message/touch_request.go +++ b/irods/message/touch_request.go @@ -101,3 +101,8 @@ func (msg *IRODSMessageTouchRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTouchRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/touch_response.go b/irods/message/touch_response.go index 7edf294..91f7191 100644 --- a/irods/message/touch_response.go +++ b/irods/message/touch_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageTouchResponse) FromMessage(msgIn *IRODSMessage) error { msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTouchResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/trim_data_object_request.go b/irods/message/trim_data_object_request.go index 4904cd4..37f91d3 100644 --- a/irods/message/trim_data_object_request.go +++ b/irods/message/trim_data_object_request.go @@ -89,3 +89,8 @@ func (msg *IRODSMessageTrimDataObjectRequest) GetMessage() (*IRODSMessage, error Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTrimDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/trim_data_object_response.go b/irods/message/trim_data_object_response.go index 40ea8d6..89995e4 100644 --- a/irods/message/trim_data_object_response.go +++ b/irods/message/trim_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageTrimDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTrimDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/truncate_data_object_request.go b/irods/message/truncate_data_object_request.go index f76f6a0..85bbd2b 100644 --- a/irods/message/truncate_data_object_request.go +++ b/irods/message/truncate_data_object_request.go @@ -76,3 +76,8 @@ func (msg *IRODSMessageTruncateDataObjectRequest) GetMessage() (*IRODSMessage, e Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTruncateDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/truncate_data_object_response.go b/irods/message/truncate_data_object_response.go index f4a4252..1992189 100644 --- a/irods/message/truncate_data_object_response.go +++ b/irods/message/truncate_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageTruncateDataObjectResponse) FromMessage(msgIn *IRODSMessa msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageTruncateDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/unlock_data_object_request.go b/irods/message/unlock_data_object_request.go index 0a44da8..3ed45f2 100644 --- a/irods/message/unlock_data_object_request.go +++ b/irods/message/unlock_data_object_request.go @@ -81,3 +81,8 @@ func (msg *IRODSMessageUnlockDataObjectRequest) GetMessage() (*IRODSMessage, err Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageUnlockDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/unlock_data_object_response.go b/irods/message/unlock_data_object_response.go index c12b387..e98ad15 100644 --- a/irods/message/unlock_data_object_response.go +++ b/irods/message/unlock_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageUnlockDataObjectResponse) FromMessage(msgIn *IRODSMessage msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageUnlockDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/user_admin_request.go b/irods/message/user_admin_request.go index 8aedae8..06c7b2b 100644 --- a/irods/message/user_admin_request.go +++ b/irods/message/user_admin_request.go @@ -110,3 +110,8 @@ func (msg *IRODSMessageUserAdminRequest) GetMessage() (*IRODSMessage, error) { Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageUserAdminRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/user_admin_response.go b/irods/message/user_admin_response.go index 5c9b8f4..57ee35a 100644 --- a/irods/message/user_admin_response.go +++ b/irods/message/user_admin_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageUserAdminResponse) FromMessage(msgIn *IRODSMessage) error msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageUserAdminResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/version.go b/irods/message/version.go index 85342b2..1ebbbc6 100644 --- a/irods/message/version.go +++ b/irods/message/version.go @@ -95,7 +95,11 @@ func (msg *IRODSMessageVersion) FromMessage(msgIn *IRODSMessage) error { err := msg.FromBytes(msgIn.Body.Message) if err != nil { - return xerrors.Errorf("failed to get irods message from message body") + return xerrors.Errorf("failed to get irods message from message body: %w", err) } return nil } + +func (msg *IRODSMessageVersion) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/write_data_object_request.go b/irods/message/write_data_object_request.go index 7a2ed0c..1434ea6 100644 --- a/irods/message/write_data_object_request.go +++ b/irods/message/write_data_object_request.go @@ -82,3 +82,8 @@ func (msg *IRODSMessageWriteDataObjectRequest) GetMessage() (*IRODSMessage, erro Body: &msgBody, }, nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageWriteDataObjectRequest) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForRequest() +} diff --git a/irods/message/write_data_object_response.go b/irods/message/write_data_object_response.go index 5a1a7c1..d35a376 100644 --- a/irods/message/write_data_object_response.go +++ b/irods/message/write_data_object_response.go @@ -29,3 +29,8 @@ func (msg *IRODSMessageWriteDataObjectResponse) FromMessage(msgIn *IRODSMessage) msg.Result = int(msgIn.Body.IntInfo) return nil } + +// GetXMLCorrector returns XML corrector for this message +func (msg *IRODSMessageWriteDataObjectResponse) GetXMLCorrector() XMLCorrector { + return GetXMLCorrectorForResponse() +} diff --git a/irods/message/xml.go b/irods/message/xml.go new file mode 100644 index 0000000..f8885b4 --- /dev/null +++ b/irods/message/xml.go @@ -0,0 +1,280 @@ +package message + +import ( + "bytes" + "fmt" + "unicode/utf8" + + "golang.org/x/xerrors" +) + +var ( + // escapes from xml.Encode + escQuot = []byte(""") // shorter than """, \" + escApos = []byte("'") // shorter than "'", \' + escTab = []byte(" ") + escNL = []byte(" ") + escCR = []byte(" ") + escFFFD = []byte("\uFFFD") // Unicode replacement character + + // escapes for irods + irodsEscQuot = []byte(""") + irodsEscApos = []byte("'") +) + +// ErrInvalidUTF8 is returned if an invalid utf-8 character is found. +var ErrInvalidUTF8 = xerrors.Errorf("invalid utf-8 character") + +// XMLCorrector is a function that corrects XML +type XMLCorrector func(msg *IRODSMessage, newXML bool) error + +// GetXMLCorrectorForRequest returns a corrector for general xml request +func GetXMLCorrectorForRequest() XMLCorrector { + return CorrectXMLRequestMessage +} + +// GetXMLCorrectorForPasswordRequest returns a corrector for password xml request +func GetXMLCorrectorForPasswordRequest() XMLCorrector { + return CorrectXMLRequestMessageForPassword +} + +// GetXMLCorrectorForResponse returns a corrector for general xml response +func GetXMLCorrectorForResponse() XMLCorrector { + return CorrectXMLResponseMessage +} + +func GetXMLCorrectorForPasswordResponse() XMLCorrector { + return CorrectXMLResponseMessageForPassword +} + +// CorrectXMLRequestMessage modifies a request message to use irods dialect for XML. +func CorrectXMLRequestMessage(msg *IRODSMessage, newXML bool) error { + if msg.Body == nil || msg.Body.Message == nil { + return nil + } + + var err error + msg.Body.Message, err = correctXMLRequest(msg.Body.Message, newXML) + + msg.Header.MessageLen = uint32(len(msg.Body.Message)) + + return err +} + +// CorrectXMLRequestMessageForPassword modifies a request message to use irods dialect for XML. +func CorrectXMLRequestMessageForPassword(msg *IRODSMessage, newXML bool) error { + if msg.Body == nil || msg.Body.Message == nil { + return nil + } + + var err error + msg.Body.Message, err = correctXMLRequestForPassword(msg.Body.Message) + + msg.Header.MessageLen = uint32(len(msg.Body.Message)) + + return err +} + +// CorrectXMLResponseMessage prepares a message that is received from irods for XML parsing. +func CorrectXMLResponseMessage(msg *IRODSMessage, newXML bool) error { + if msg.Body == nil || msg.Body.Message == nil { + return nil + } + + var err error + + msg.Body.Message, err = correctXMLResponse(msg.Body.Message, newXML) + msg.Header.MessageLen = uint32(len(msg.Body.Message)) + + return err +} + +// CorrectXMLResponseMessageForPassword prepares a message that is received from irods for XML parsing. +func CorrectXMLResponseMessageForPassword(msg *IRODSMessage, newXML bool) error { + if msg.Body == nil || msg.Body.Message == nil { + return nil + } + + var err error + + msg.Body.Message, err = correctXMLResponseForPassword(msg.Body.Message, newXML) + msg.Header.MessageLen = uint32(len(msg.Body.Message)) + + return err +} + +// correctXMLRequest translates output of xml.Marshal into XML that IRODS understands. +func correctXMLRequest(in []byte, newXML bool) ([]byte, error) { + buf := in + out := &bytes.Buffer{} + + for len(buf) > 0 { + switch { + // turn " into " + case bytes.HasPrefix(buf, escQuot): + out.Write(irodsEscQuot) + buf = buf[len(escQuot):] + // turn ' into ' or ' + case bytes.HasPrefix(buf, escApos): + if newXML { + out.Write(irodsEscApos) + } else { + out.WriteByte('\'') + } + buf = buf[len(escApos):] + // irods does not decode encoded tabs + case bytes.HasPrefix(buf, escTab): + out.WriteByte('\t') + buf = buf[len(escTab):] + // irods does not decode encoded carriage returns + case bytes.HasPrefix(buf, escCR): + out.WriteByte('\r') + buf = buf[len(escCR):] + // irods does not decode encoded newlines + case bytes.HasPrefix(buf, escNL): + out.WriteByte('\n') + buf = buf[len(escNL):] + // turn ` into ' + case buf[0] == '`' && !newXML: + out.Write(irodsEscApos) + buf = buf[1:] + // pass utf8 characters + default: + r, size := utf8.DecodeRune(buf) + if r == utf8.RuneError && size == 1 { + return in, ErrInvalidUTF8 + } + + out.Write(buf[:size]) + buf = buf[size:] + } + } + + return out.Bytes(), nil +} + +// correctXMLRequestForPassword translates output of xml.Marshal into XML that IRODS understands. +func correctXMLRequestForPassword(in []byte) ([]byte, error) { + buf := in + out := &bytes.Buffer{} + + for len(buf) > 0 { + switch { + // turn " into \" + case bytes.HasPrefix(buf, escQuot): + out.WriteByte('"') + buf = buf[len(escQuot):] + // turn ' into \' + case bytes.HasPrefix(buf, escApos): + out.WriteByte('\'') + buf = buf[len(escApos):] + // irods does not decode encoded tabs + case bytes.HasPrefix(buf, escTab): + out.WriteByte('\t') + buf = buf[len(escTab):] + // irods does not decode encoded carriage returns + case bytes.HasPrefix(buf, escCR): + out.WriteByte('\r') + buf = buf[len(escCR):] + // irods does not decode encoded newlines + case bytes.HasPrefix(buf, escNL): + out.WriteByte('\n') + buf = buf[len(escNL):] + // pass utf8 characters + default: + r, size := utf8.DecodeRune(buf) + if r == utf8.RuneError && size == 1 { + return in, ErrInvalidUTF8 + } + + out.Write(buf[:size]) + buf = buf[size:] + } + } + + return out.Bytes(), nil +} + +// correctXMLResponse translates IRODS XML into valid XML. +// We fix the invalid encoding of ` as ". +func correctXMLResponse(in []byte, newXML bool) ([]byte, error) { + buf := in + out := &bytes.Buffer{} + + for len(buf) > 0 { + switch { + // turn " into ` + case bytes.HasPrefix(buf, irodsEscQuot) && !newXML: + out.WriteByte('`') + buf = buf[len(irodsEscQuot):] + // turn ' into ' + case buf[0] == '\'' && !newXML: + out.Write(escApos) + buf = buf[1:] + // check utf8 characters for validity + default: + r, size := utf8.DecodeRune(buf) + if r == utf8.RuneError && size == 1 { + return in, ErrInvalidUTF8 + } + + if isValidUTF8(buf[:size]) { + out.Write(buf[:size]) + } else { + out.Write(escFFFD) + } + + buf = buf[size:] + } + } + + return out.Bytes(), nil +} + +// correctXMLResponseForPassword translates IRODS XML into valid XML. +// We fix the invalid encoding of ` as ". +func correctXMLResponseForPassword(in []byte, newXML bool) ([]byte, error) { + //logger.Debugf("in (quoted): %q, len: %d", in, len(in)) + //logger.Debugf("in (string): %s, len: %d", in, len(in)) + + buf := in + out := &bytes.Buffer{} + + for len(buf) > 0 { + switch { + // turn " into ` + case bytes.HasPrefix(buf, irodsEscQuot) && !newXML: + out.WriteByte('`') + buf = buf[len(irodsEscQuot):] + // turn ' into ' + case buf[0] == '\'' && !newXML: + out.Write(escApos) + buf = buf[1:] + // check utf8 characters for validity + default: + if !isValidUTF8Char(buf[0]) { + out.WriteString(fmt.Sprintf("0x%x", buf[:1])) + } else { + out.Write(buf[:1]) + } + + buf = buf[1:] + } + } + + //logger.Debugf("out (quoted): %q, len: %d", out.Bytes(), len(out.Bytes())) + //logger.Debugf("out (string): %s, len: %d", out.Bytes(), len(out.Bytes())) + + return out.Bytes(), nil +} + +func isValidUTF8(data []byte) bool { + return utf8.Valid(data) +} + +func isValidUTF8Char(ch byte) bool { + return ch == 0x09 || // \t + ch == 0x0A || // \n + ch == 0x0D || // \r + (ch >= 0x20 && ch <= 0x7E) +} diff --git a/irods/types/account.go b/irods/types/account.go index f6c6862..a25e2ef 100644 --- a/irods/types/account.go +++ b/irods/types/account.go @@ -10,7 +10,7 @@ import ( const ( // PamTTLDefault is a default value for Pam TTL - PamTTLDefault int = 1 + PamTTLDefault int = 0 // sever decides UsernameRegexString string = "^((\\w|[-.@])+)$" HashSchemeDefault string = "SHA256" ) diff --git a/irods/types/auth.go b/irods/types/auth.go index 1233975..a0af637 100644 --- a/irods/types/auth.go +++ b/irods/types/auth.go @@ -14,6 +14,8 @@ const ( AuthSchemeGSI AuthScheme = "gsi" // AuthSchemePAM uses PAM authentication scheme AuthSchemePAM AuthScheme = "pam" + // AuthSchemePAMPasswordAuthScheme uses PAM authentication scheme + AuthSchemePAMPassword AuthScheme = "pam_password" // AuthSchemeUnknown is unknown scheme AuthSchemeUnknown AuthScheme = "" ) @@ -25,11 +27,18 @@ func GetAuthScheme(authScheme string) AuthScheme { return AuthSchemeNative case string(AuthSchemeGSI): return AuthSchemeGSI - case string(AuthSchemePAM), "pam_password": + case string(AuthSchemePAM): return AuthSchemePAM + case string(AuthSchemePAMPassword): + return AuthSchemePAMPassword case string(AuthSchemeUnknown): fallthrough default: return AuthSchemeUnknown } } + +// IsPAM checks if the auth scheme is pam or pam_password +func (authScheme AuthScheme) IsPAM() bool { + return authScheme == AuthSchemePAM || authScheme == AuthSchemePAMPassword +} diff --git a/python/pam.py b/python/pam.py new file mode 100644 index 0000000..2a5d309 --- /dev/null +++ b/python/pam.py @@ -0,0 +1,22 @@ +import os +import logging +from irods.session import iRODSSession +import irods.client_configuration as cfg +try: + env_file = os.environ['IRODS_ENVIRONMENT_FILE'] + auth_file = os.environ['IRODS_AUTHENTICATION_FILE'] +except KeyError: + env_file = os.path.expanduser('~/.irods/irods_environment.json') + auth_file = os.path.expanduser('~/.irods/.irodsA') + +logging.basicConfig(level=logging.DEBUG) + +cfg.load() + +ssl_settings = {} # Or, optionally: {'ssl_context': } +session = iRODSSession(irods_env_file=env_file, **ssl_settings) +session.pool.account._auth_file = auth_file +coll = session.collections.get("/%s/home/%s" % (session.zone, session.username)) + +for obj in coll.data_objects: + print(obj)