gitlab.com/evatix-go/core@v1.3.55/chmodhelper/chmodVerifier.go (about)

     1  package chmodhelper
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  
     7  	"gitlab.com/evatix-go/core/chmodhelper/chmodins"
     8  	"gitlab.com/evatix-go/core/constants"
     9  	"gitlab.com/evatix-go/core/coredata/corestr"
    10  	"gitlab.com/evatix-go/core/errcore"
    11  	"gitlab.com/evatix-go/core/internal/fsinternal"
    12  )
    13  
    14  type chmodVerifier struct{}
    15  
    16  // IsEqualRwxFull
    17  //
    18  //  expectedHyphenedRwx must be 10 chars in "-rwxrwxrwx"
    19  //
    20  //  Hint. os.FileMode. String() returns "-rwxrwxrwx" full rwx
    21  //  https://go.dev/play/p/Qq_rKl_pAqe
    22  //
    23  // Format (length must be 10)
    24  //  "-rwxrwxrwx"
    25  //
    26  // Example:
    27  //  - owner all enabled only "-rwx------"
    28  //  - group all enabled only "----rwx---"
    29  //
    30  // Must have or restrictions:
    31  //  - string length must be 10.
    32  //
    33  // Reference:
    34  //  - https://ss64.com/bash/chmod.html
    35  func (it chmodVerifier) IsEqualRwxFull(
    36  	location string,
    37  	expectedHyphenedRwx string,
    38  ) bool {
    39  	return IsChmod(
    40  		location,
    41  		expectedHyphenedRwx)
    42  }
    43  
    44  // IsEqualRwxFullSkipInvalid
    45  //
    46  //  On invalid path it is assumed to be equal.
    47  //  expectedHyphenedRwx must be 10 chars in "-rwxrwxrwx"
    48  //
    49  //  Hint. os.FileMode. String() returns "-rwxrwxrwx" full rwx
    50  //  https://go.dev/play/p/Qq_rKl_pAqe
    51  //
    52  // Format (length must be 10)
    53  //  "-rwxrwxrwx"
    54  //
    55  // Example:
    56  //  - owner all enabled only "-rwx------"
    57  //  - group all enabled only "----rwx---"
    58  //
    59  // Must have or restrictions:
    60  //  - string length must be 10.
    61  //
    62  // Reference:
    63  //  - https://ss64.com/bash/chmod.html
    64  func (it chmodVerifier) IsEqualRwxFullSkipInvalid(
    65  	location string,
    66  	expectedHyphenedRwx string,
    67  ) bool {
    68  	if fsinternal.IsPathInvalid(location) {
    69  		return true
    70  	}
    71  
    72  	return IsChmod(
    73  		location,
    74  		expectedHyphenedRwx)
    75  }
    76  
    77  func (it chmodVerifier) IsEqual(
    78  	location string,
    79  	expectedFileMode os.FileMode,
    80  ) bool {
    81  	return IsChmod(
    82  		location,
    83  		expectedFileMode.String())
    84  }
    85  
    86  // IsEqualSkipInvalid
    87  //
    88  //  On invalid path it is assumed to be equal.
    89  func (it chmodVerifier) IsEqualSkipInvalid(
    90  	location string,
    91  	expectedFileMode os.FileMode,
    92  ) bool {
    93  	if fsinternal.IsPathInvalid(location) {
    94  		return true
    95  	}
    96  
    97  	return IsChmod(
    98  		location,
    99  		expectedFileMode.String())
   100  }
   101  
   102  func (it chmodVerifier) IsMismatch(
   103  	location string,
   104  	expectedFileMode os.FileMode,
   105  ) bool {
   106  	return !IsChmod(
   107  		location,
   108  		expectedFileMode.String())
   109  }
   110  
   111  func (it chmodVerifier) MismatchError(
   112  	location string,
   113  	expectedFileMode os.FileMode,
   114  ) error {
   115  	return it.RwxFull(
   116  		location,
   117  		expectedFileMode.String())
   118  }
   119  
   120  func (it chmodVerifier) MismatchErrorUsingRwxFull(
   121  	location string,
   122  	rwxFull string,
   123  ) error {
   124  	return it.RwxFull(
   125  		location,
   126  		rwxFull)
   127  }
   128  
   129  // GetRwxFull
   130  //
   131  //  Hint. os.FileMode. String() returns "-rwxrwxrwx" full rwx
   132  //  https://go.dev/play/p/Qq_rKl_pAqe
   133  func (it chmodVerifier) GetRwxFull(fileMode os.FileMode) string {
   134  	return fileMode.String()
   135  }
   136  
   137  // GetRwx9
   138  //
   139  //  return "rwxrwxrwx"
   140  //
   141  //  Hint. os.FileMode. String() returns "-rwxrwxrwx" full rwx
   142  //  then substring "-rwxrwxrwx"[1:] to return "rwxrwxrwx"
   143  //
   144  //  https://go.dev/play/p/Qq_rKl_pAqe
   145  //
   146  // Format (length must be 9)
   147  //  "rwxrwxrwx"
   148  //
   149  // Understanding Examples:
   150  //  - owner all enabled only "rwx------"
   151  //  - group all enabled only "---rwx---"
   152  //
   153  // Reference:
   154  //  - Chmod examples      : https://ss64.com/bash/chmod.html
   155  //  - FileMode to RwxFull : https://go.dev/play/p/Qq_rKl_pAqe
   156  func (it chmodVerifier) GetRwx9(fileMode os.FileMode) string {
   157  	rwxFull := fileMode.String()
   158  
   159  	if len(rwxFull) > 9 {
   160  		return rwxFull[1:]
   161  	}
   162  
   163  	return ""
   164  }
   165  
   166  func (it chmodVerifier) GetExisting(
   167  	filePath string,
   168  ) (os.FileMode, error) {
   169  	return GetExistingChmod(filePath)
   170  }
   171  
   172  func (it chmodVerifier) GetExistingRwxWrapper(
   173  	location string,
   174  ) (RwxWrapper, error) {
   175  	return GetExistingChmodRwxWrapper(location)
   176  }
   177  
   178  func (it chmodVerifier) GetExistingRwxWrapperMust(
   179  	location string,
   180  ) RwxWrapper {
   181  	rwx, err := GetExistingChmodRwxWrapper(location)
   182  
   183  	if err != nil {
   184  		panic(err)
   185  	}
   186  
   187  	return rwx
   188  }
   189  
   190  func (it chmodVerifier) GetExistingChmodRwxWrappers(
   191  	isContinueOnError bool,
   192  	locations ...string,
   193  ) (filePathToRwxWrapper map[string]*RwxWrapper, err error) {
   194  	return GetExistingChmodRwxWrappers(
   195  		isContinueOnError,
   196  		locations...)
   197  }
   198  
   199  func (it chmodVerifier) GetExistsFilteredPathFileInfoMap(
   200  	isSkipOnInvalid bool,
   201  	locations ...string,
   202  ) *FilteredPathFileInfoMap {
   203  	return GetExistsFilteredPathFileInfoMap(
   204  		isSkipOnInvalid,
   205  		locations...)
   206  }
   207  
   208  func (it chmodVerifier) PathIf(
   209  	isVerify bool,
   210  	location string,
   211  	expectedFileMode os.FileMode,
   212  ) error {
   213  	if !isVerify {
   214  		return nil
   215  	}
   216  
   217  	return it.RwxFull(
   218  		location,
   219  		expectedFileMode.String())
   220  }
   221  
   222  func (it chmodVerifier) Path(
   223  	location string,
   224  	expectedFileMode os.FileMode,
   225  ) error {
   226  	return it.RwxFull(
   227  		location,
   228  		expectedFileMode.String())
   229  }
   230  
   231  // RwxFull
   232  //
   233  //  expectedHyphenedRwx must be 10 chars in "-rwxrwxrwx"
   234  //  Hint. os.FileMode.String() returns "-rwxrwxrwx" full rwx
   235  //  https://go.dev/play/p/Qq_rKl_pAqe
   236  //
   237  // Format (length must be 10)
   238  //  "-rwxrwxrwx"
   239  //
   240  // Example:
   241  //  - owner all enabled only "-rwx------"
   242  //  - group all enabled only "----rwx---"
   243  //
   244  // Must have or restrictions:
   245  //  - string length must be 10.
   246  //
   247  // Reference:
   248  //  - https://ss64.com/bash/chmod.html
   249  func (it chmodVerifier) RwxFull(
   250  	location,
   251  	expectedHyphenedRwx string,
   252  ) error {
   253  	if len(expectedHyphenedRwx) != HyphenedRwxLength {
   254  		return errcore.MeaningfulError(
   255  			errcore.LengthShouldBeEqualToType,
   256  			"VerifyChmod"+constants.HyphenAngelRight+location,
   257  			errHyphenedRwxLength)
   258  	}
   259  
   260  	fileInfo, err := os.Stat(location)
   261  
   262  	if os.IsNotExist(err) || fileInfo == nil {
   263  		return errcore.MeaningfulError(
   264  			errcore.PathInvalidErrorType,
   265  			"VerifyChmod"+constants.HyphenAngelRight+location,
   266  			err)
   267  	}
   268  
   269  	existingFileMode := fileInfo.Mode().String()[1:]
   270  	if existingFileMode == expectedHyphenedRwx[1:] {
   271  		return nil
   272  	}
   273  
   274  	expectationFailedMessage := errcore.ExpectingSimpleNoType(
   275  		chmodExpectationFailed,
   276  		expectedHyphenedRwx,
   277  		existingFileMode)
   278  
   279  	return errcore.MeaningfulError(
   280  		errcore.PathChmodMismatchErrorType,
   281  		"VerifyChmod"+constants.HyphenAngelRight+location,
   282  		errors.New(expectationFailedMessage))
   283  }
   284  
   285  // PathsUsingPartialRwxOptions
   286  //
   287  // partialRwx can be any length in
   288  // between 1-10 (rest will be fixed by wildcard)
   289  //
   290  // partialRwx:
   291  //  - "-rwx"    will be "-rwx******"
   292  //  - "-rwxr-x" will be "-rwxr-x***"
   293  //  - "-rwxr-x" will be "-rwxr-x***"
   294  //
   295  // partialRwx Restrictions:
   296  //  - cannot have first char other than hyphen(-) or else things will not work
   297  //
   298  // Options:
   299  //  - isContinueOnError : on true don't stop until all locations are captured.
   300  //  - isSkipOnInvalid   : on true invalid paths will not be considered into expectation.
   301  func (it chmodVerifier) PathsUsingPartialRwxOptions(
   302  	isContinueOnError,
   303  	isSkipOnInvalid bool,
   304  	partialRwx string,
   305  	locations ...string,
   306  ) error {
   307  	varWrapper, err := NewRwxVariableWrapper(partialRwx)
   308  
   309  	if err != nil {
   310  		return err
   311  	}
   312  
   313  	status := varWrapper.RwxMatchingStatus(
   314  		isContinueOnError,
   315  		isSkipOnInvalid,
   316  		locations)
   317  
   318  	return status.CreateErrFinalError()
   319  }
   320  
   321  // PathsUsingFileModeImmediateReturn
   322  //
   323  // on error quick return, don't wait for all.
   324  func (it chmodVerifier) PathsUsingFileModeImmediateReturn(
   325  	fileMode os.FileMode,
   326  	locations ...string,
   327  ) error {
   328  	return it.PathsUsingRwxFull(
   329  		false,
   330  		fileMode.String(),
   331  		locations...)
   332  }
   333  
   334  // PathsUsingFileModeContinueOnError
   335  //
   336  // continue on error and return collected error
   337  func (it chmodVerifier) PathsUsingFileModeContinueOnError(
   338  	fileMode os.FileMode,
   339  	locations ...string,
   340  ) error {
   341  	return it.PathsUsingRwxFull(
   342  		true,
   343  		fileMode.String(),
   344  		locations...)
   345  }
   346  
   347  // PathsUsingFileMode
   348  //
   349  // Options:
   350  //  - isContinueOnError : on true don't stop until all locations are captured.
   351  func (it chmodVerifier) PathsUsingFileMode(
   352  	isContinueOnError bool,
   353  	fileMode os.FileMode,
   354  	locations ...string,
   355  ) error {
   356  	return it.PathsUsingRwxFull(
   357  		isContinueOnError,
   358  		fileMode.String(),
   359  		locations...)
   360  }
   361  
   362  // PathsUsingRwxFull
   363  //
   364  // expectedHyphenedRwx Format (length must be 10)
   365  //  "-rwxrwxrwx"
   366  //  Hint. os.FileMode. String() returns "-rwxrwxrwx" full rwx
   367  //  https://go.dev/play/p/Qq_rKl_pAqe
   368  //
   369  // expectedHyphenedRwx Example:
   370  //  - owner all enabled only "-rwx------"
   371  //  - group all enabled only "----rwx---"
   372  //
   373  // expectedHyphenedRwx Must have or restrictions:
   374  //  - string length must be 10.
   375  //
   376  // Reference:
   377  //  - https://ss64.com/bash/chmod.html
   378  //
   379  // Options:
   380  //  - isContinueOnError : on true don't stop until all locations are captured.
   381  func (it chmodVerifier) PathsUsingRwxFull(
   382  	isContinueOnError bool,
   383  	expectedHyphenedRwx string,
   384  	locations ...string,
   385  ) error {
   386  	if locations == nil || len(locations) == 0 {
   387  		return errcore.CannotBeNilOrEmptyType.
   388  			Error(constants.EmptyString, nil)
   389  	}
   390  
   391  	if !isContinueOnError {
   392  		for _, location := range locations {
   393  			err := it.RwxFull(location, expectedHyphenedRwx)
   394  
   395  			if err != nil {
   396  				return err
   397  			}
   398  		}
   399  	}
   400  
   401  	slice := corestr.New.Collection.Cap(constants.Zero)
   402  
   403  	for _, location := range locations {
   404  		err := it.RwxFull(location, expectedHyphenedRwx)
   405  
   406  		//goland:noinspection ALL
   407  		slice.AddIf(err != nil, err.Error())
   408  	}
   409  
   410  	return errcore.SliceErrorDefault(slice.ListPtr())
   411  }
   412  
   413  // UsingHashmap
   414  //
   415  //  Key - > Path, Value -> RwxFullString (10 chars, "-rwx------")
   416  //
   417  // map[key]RwxFullValue - RwxFullValue - Format (length must be 10)
   418  //  "-rwxrwxrwx"
   419  //
   420  // RwxFullString Example:
   421  //  - owner all enabled only "-rwx------"
   422  //  - group all enabled only "----rwx---"
   423  //
   424  // RwxFullString Must have or restrictions:
   425  //  - string length must be 10.
   426  //
   427  // RwxFullString Reference:
   428  //  - https://ss64.com/bash/chmod.html
   429  //
   430  // Multiple files verification error will be returned as once.
   431  // nil will be returned if no error
   432  func (it chmodVerifier) UsingHashmap(
   433  	filePathToRwxMap *corestr.Hashmap,
   434  ) error {
   435  	var sliceError []string
   436  
   437  	for filePath, expectedRwxFull := range filePathToRwxMap.Items() {
   438  		err := it.RwxFull(filePath, expectedRwxFull)
   439  
   440  		if err != nil {
   441  			sliceError = append(sliceError, err.Error())
   442  		}
   443  	}
   444  
   445  	return errcore.SliceToError(sliceError)
   446  }
   447  
   448  func (it chmodVerifier) UsingRwxOwnerGroupOther(
   449  	rwx *chmodins.RwxOwnerGroupOther,
   450  	location string,
   451  ) error {
   452  	if rwx == nil {
   453  		return errcore.
   454  			CannotBeNilOrEmptyType.
   455  			Error("rwx is nil", location)
   456  	}
   457  
   458  	return it.RwxFull(
   459  		location,
   460  		rwx.String())
   461  }