Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F99021824
PhabricatorFilesManagementIntegrityWorkflow.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Jan 18, 13:09
Size
8 KB
Mime Type
text/x-php
Expires
Mon, Jan 20, 13:09 (2 d)
Engine
blob
Format
Raw Data
Handle
23689054
Attached To
rPH Phabricator
PhabricatorFilesManagementIntegrityWorkflow.php
View Options
<?php
final
class
PhabricatorFilesManagementIntegrityWorkflow
extends
PhabricatorFilesManagementWorkflow
{
protected
function
didConstruct
()
{
$this
->
setName
(
'integrity'
)
->
setSynopsis
(
pht
(
'Verify or recalculate file integrity hashes.'
))
->
setArguments
(
array
(
array
(
'name'
=>
'all'
,
'help'
=>
pht
(
'Affect all files.'
),
),
array
(
'name'
=>
'strip'
,
'help'
=>
pht
(
'DANGEROUS. Strip integrity hashes from files. This makes '
.
'files vulnerable to corruption or tampering.'
),
),
array
(
'name'
=>
'corrupt'
,
'help'
=>
pht
(
'Corrupt integrity hashes for given files. This is intended '
.
'for debugging.'
),
),
array
(
'name'
=>
'compute'
,
'help'
=>
pht
(
'Compute and update integrity hashes for files which do not '
.
'yet have them.'
),
),
array
(
'name'
=>
'overwrite'
,
'help'
=>
pht
(
'DANGEROUS. Recompute and update integrity hashes, overwriting '
.
'invalid hashes. This may mark corrupt or dangerous files as '
.
'valid.'
),
),
array
(
'name'
=>
'force'
,
'short'
=>
'f'
,
'help'
=>
pht
(
'Execute dangerous operations without prompting for '
.
'confirmation.'
),
),
array
(
'name'
=>
'names'
,
'wildcard'
=>
true
,
),
));
}
public
function
execute
(
PhutilArgumentParser
$args
)
{
$modes
=
array
();
$is_strip
=
$args
->
getArg
(
'strip'
);
if
(
$is_strip
)
{
$modes
[]
=
'strip'
;
}
$is_corrupt
=
$args
->
getArg
(
'corrupt'
);
if
(
$is_corrupt
)
{
$modes
[]
=
'corrupt'
;
}
$is_compute
=
$args
->
getArg
(
'compute'
);
if
(
$is_compute
)
{
$modes
[]
=
'compute'
;
}
$is_overwrite
=
$args
->
getArg
(
'overwrite'
);
if
(
$is_overwrite
)
{
$modes
[]
=
'overwrite'
;
}
$is_verify
=
!
$modes
;
if
(
$is_verify
)
{
$modes
[]
=
'verify'
;
}
if
(
count
(
$modes
)
>
1
)
{
throw
new
PhutilArgumentUsageException
(
pht
(
'You have selected multiple operation modes (%s). Choose a '
.
'single mode to operate in.'
,
implode
(
', '
,
$modes
)));
}
$is_force
=
$args
->
getArg
(
'force'
);
if
(!
$is_force
)
{
$prompt
=
null
;
if
(
$is_strip
)
{
$prompt
=
pht
(
'Stripping integrity hashes is dangerous and makes files '
.
'vulnerable to corruption or tampering.'
);
}
if
(
$is_corrupt
)
{
$prompt
=
pht
(
'Corrupting integrity hashes will prevent files from being '
.
'accessed. This mode is intended only for development and '
.
'debugging.'
);
}
if
(
$is_overwrite
)
{
$prompt
=
pht
(
'Overwriting integrity hashes is dangerous and may mark files '
.
'which have been corrupted or tampered with as safe.'
);
}
if
(
$prompt
)
{
$this
->
logWarn
(
pht
(
'DANGEROUS'
),
$prompt
);
if
(!
phutil_console_confirm
(
pht
(
'Continue anyway?'
)))
{
throw
new
PhutilArgumentUsageException
(
pht
(
'Aborted workflow.'
));
}
}
}
$iterator
=
$this
->
buildIterator
(
$args
);
if
(!
$iterator
)
{
throw
new
PhutilArgumentUsageException
(
pht
(
'Either specify a list of files to affect, or use "--all" to '
.
'affect all files.'
));
}
$failure_count
=
0
;
$total_count
=
0
;
foreach
(
$iterator
as
$file
)
{
$total_count
++;
$display_name
=
$file
->
getMonogram
();
$old_hash
=
$file
->
getIntegrityHash
();
if
(
$is_strip
)
{
if
(
$old_hash
===
null
)
{
$this
->
logInfo
(
pht
(
'SKIPPED'
),
pht
(
'File "%s" does not have an integrity hash to strip.'
,
$display_name
));
}
else
{
$file
->
setIntegrityHash
(
null
)
->
save
();
$this
->
logWarn
(
pht
(
'STRIPPED'
),
pht
(
'Stripped integrity hash for "%s".'
,
$display_name
));
}
continue
;
}
$need_hash
=
(
$is_verify
&&
$old_hash
)
||
(
$is_compute
&&
(
$old_hash
===
null
))
||
(
$is_corrupt
)
||
(
$is_overwrite
);
if
(
$need_hash
)
{
try
{
$new_hash
=
$file
->
newIntegrityHash
();
}
catch
(
Exception
$ex
)
{
$failure_count
++;
$this
->
logFail
(
pht
(
'ERROR'
),
pht
(
'Unable to compute integrity hash for file "%s": %s'
,
$display_name
,
$ex
->
getMessage
()));
continue
;
}
}
else
{
$new_hash
=
null
;
}
// NOTE: When running in "corrupt" mode, we only corrupt the hash if
// we're able to compute a valid hash. Some files, like chunked files,
// do not support integrity hashing so corrupting them would create an
// unusual state.
if
(
$is_corrupt
)
{
if
(
$new_hash
===
null
)
{
$this
->
logInfo
(
pht
(
'IGNORED'
),
pht
(
'Storage for file "%s" does not support integrity hashing.'
,
$display_name
));
}
else
{
$file
->
setIntegrityHash
(
'<corrupted>'
)
->
save
();
$this
->
logWarn
(
pht
(
'CORRUPTED'
),
pht
(
'Corrupted integrity hash for file "%s".'
,
$display_name
));
}
continue
;
}
if
(
$is_verify
)
{
if
(
$old_hash
===
null
)
{
$this
->
logInfo
(
pht
(
'NONE'
),
pht
(
'File "%s" has no stored integrity hash.'
,
$display_name
));
}
else
if
(
$new_hash
===
null
)
{
$failure_count
++;
$this
->
logWarn
(
pht
(
'UNEXPECTED'
),
pht
(
'Storage for file "%s" does not support integrity hashing, '
.
'but the file has an integrity hash.'
,
$display_name
));
}
else
if
(
phutil_hashes_are_identical
(
$old_hash
,
$new_hash
))
{
$this
->
logOkay
(
pht
(
'VALID'
),
pht
(
'File "%s" has a valid integrity hash.'
,
$display_name
));
}
else
{
$failure_count
++;
$this
->
logFail
(
pht
(
'MISMATCH'
),
pht
(
'File "%s" has an invalid integrity hash!'
,
$display_name
));
}
continue
;
}
if
(
$is_compute
)
{
if
(
$old_hash
!==
null
)
{
$this
->
logInfo
(
pht
(
'SKIP'
),
pht
(
'File "%s" already has an integrity hash.'
,
$display_name
));
}
else
if
(
$new_hash
===
null
)
{
$this
->
logInfo
(
pht
(
'IGNORED'
),
pht
(
'Storage for file "%s" does not support integrity hashing.'
,
$display_name
));
}
else
{
$file
->
setIntegrityHash
(
$new_hash
)
->
save
();
$this
->
logOkay
(
pht
(
'COMPUTE'
),
pht
(
'Computed and stored integrity hash for file "%s".'
,
$display_name
));
}
continue
;
}
if
(
$is_overwrite
)
{
$same_hash
=
(
$old_hash
!==
null
)
&&
(
$new_hash
!==
null
)
&&
phutil_hashes_are_identical
(
$old_hash
,
$new_hash
);
if
(
$new_hash
===
null
)
{
$this
->
logInfo
(
pht
(
'IGNORED'
),
pht
(
'Storage for file "%s" does not support integrity hashing.'
,
$display_name
));
}
else
if
(
$same_hash
)
{
$this
->
logInfo
(
pht
(
'UNCHANGED'
),
pht
(
'File "%s" already has the correct integrity hash.'
,
$display_name
));
}
else
{
$file
->
setIntegrityHash
(
$new_hash
)
->
save
();
$this
->
logOkay
(
pht
(
'OVERWRITE'
),
pht
(
'Overwrote integrity hash for file "%s".'
,
$display_name
));
}
continue
;
}
}
if
(
$failure_count
)
{
$this
->
logFail
(
pht
(
'FAIL'
),
pht
(
'Processed %s file(s), encountered %s error(s).'
,
new
PhutilNumber
(
$total_count
),
new
PhutilNumber
(
$failure_count
)));
}
else
{
$this
->
logOkay
(
pht
(
'DONE'
),
pht
(
'Processed %s file(s) with no errors.'
,
new
PhutilNumber
(
$total_count
)));
}
return
0
;
}
}
Event Timeline
Log In to Comment