Skip to content

Commit

Permalink
fix time comparison by having utc time both the sides (#115)
Browse files Browse the repository at this point in the history
Signed-off-by: Bala.FA <[email protected]>
  • Loading branch information
balamurugana authored Mar 18, 2024
1 parent 765ec24 commit c43db14
Show file tree
Hide file tree
Showing 17 changed files with 136 additions and 130 deletions.
2 changes: 1 addition & 1 deletion examples/GetPresignedPostFormData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int main() {
minio::s3::Client client(base_url, &provider);

// Create get presigned post form data arguments.
minio::utils::Time expiration = minio::utils::Time::Now();
minio::utils::UtcTime expiration = minio::utils::UtcTime::Now();
expiration.Add(60 * 60 * 24); // 1 day from now.
minio::s3::PostPolicy policy("my-bucket", expiration);
policy.AddStartsWithCondition("key", "my/object/prefix/");
Expand Down
2 changes: 1 addition & 1 deletion examples/SetObjectRetention.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int main() {
args.bucket = "my-bucket";
args.object = "my-object";
args.retention_mode = minio::s3::RetentionMode::kGovernance;
minio::utils::Time tomorrow = minio::utils::Time::Now();
minio::utils::UtcTime tomorrow = minio::utils::UtcTime::Now();
tomorrow.Add(60 * 60 * 24);
args.retain_until_date = tomorrow;

Expand Down
15 changes: 8 additions & 7 deletions include/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ struct ObjectConditionalReadArgs : public ObjectReadArgs {
size_t *length = nullptr;
std::string match_etag;
std::string not_match_etag;
utils::Time modified_since;
utils::Time unmodified_since;
utils::UtcTime modified_since;
utils::UtcTime unmodified_since;

ObjectConditionalReadArgs() = default;
~ObjectConditionalReadArgs() = default;
Expand Down Expand Up @@ -488,7 +488,7 @@ using GetObjectRetentionArgs = ObjectVersionArgs;

struct SetObjectRetentionArgs : public ObjectVersionArgs {
RetentionMode retention_mode;
utils::Time retain_until_date;
utils::UtcTime retain_until_date;

SetObjectRetentionArgs() = default;
~SetObjectRetentionArgs() = default;
Expand All @@ -502,7 +502,7 @@ inline constexpr unsigned int kDefaultExpirySeconds =
struct GetPresignedObjectUrlArgs : public ObjectVersionArgs {
http::Method method;
unsigned int expiry_seconds = kDefaultExpirySeconds;
utils::Time request_time;
utils::UtcTime request_time;

GetPresignedObjectUrlArgs() = default;
~GetPresignedObjectUrlArgs() = default;
Expand All @@ -514,7 +514,7 @@ struct PostPolicy {
std::string bucket;
std::string region;

PostPolicy(std::string bucket, utils::Time expiration)
PostPolicy(std::string bucket, utils::UtcTime expiration)
: bucket(std::move(bucket)), expiration_(std::move(expiration)) {}

~PostPolicy() = default;
Expand All @@ -538,14 +538,15 @@ struct PostPolicy {
static constexpr const char *starts_with_ = "starts-with";
static constexpr const char *algorithm_ = "AWS4-HMAC-SHA256";

utils::Time expiration_;
utils::UtcTime expiration_;
std::map<std::string, std::map<std::string, std::string>> conditions_;
Integer lower_limit_;
Integer upper_limit_;

static std::string trimDollar(std::string value);
static std::string getCredentialString(std::string access_key,
utils::Time date, std::string region);
utils::UtcTime date,
std::string region);
static bool isReservedElement(std::string element);
}; // struct PostPolicy
} // namespace s3
Expand Down
4 changes: 2 additions & 2 deletions include/credentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

namespace minio {
namespace creds {
bool expired(const utils::Time& expiration);
bool expired(const utils::UtcTime& expiration);

/**
* Credentials contains access key and secret key with optional session token
Expand All @@ -31,7 +31,7 @@ struct Credentials {
std::string access_key = {};
std::string secret_key = {};
std::string session_token = {};
utils::Time expiration = {};
utils::UtcTime expiration = {};

Credentials() = default;
~Credentials() = default;
Expand Down
2 changes: 1 addition & 1 deletion include/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct Request {
void* progress_userdata = nullptr;

std::string sha256;
utils::Time date;
utils::UtcTime date;

bool debug = false;
bool ignore_cert_check = false;
Expand Down
8 changes: 4 additions & 4 deletions include/response.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ struct StatObjectResponse : public Response {
std::string version_id;
std::string etag;
size_t size = 0;
utils::Time last_modified;
utils::UtcTime last_modified;
RetentionMode retention_mode;
utils::Time retention_retain_until_date;
utils::UtcTime retention_retain_until_date;
LegalHold legal_hold;
bool delete_marker;
utils::Multimap user_metadata;
Expand All @@ -185,7 +185,7 @@ using GetObjectResponse = Response;
struct Item : public Response {
std::string etag; // except DeleteMarker
std::string name;
utils::Time last_modified;
utils::UtcTime last_modified;
std::string owner_id;
std::string owner_name;
size_t size = 0; // except DeleteMarker
Expand Down Expand Up @@ -478,7 +478,7 @@ struct IsObjectLegalHoldEnabledResponse : public Response {

struct GetObjectRetentionResponse : public Response {
RetentionMode retention_mode;
utils::Time retain_until_date;
utils::UtcTime retain_until_date;

GetObjectRetentionResponse() = default;

Expand Down
18 changes: 10 additions & 8 deletions include/signer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,20 @@

namespace minio {
namespace signer {
std::string GetScope(const utils::Time& time, const std::string& region,
std::string GetScope(const utils::UtcTime& time, const std::string& region,
const std::string& service_name);
std::string GetCanonicalRequestHash(const std::string& method,
const std::string& uri,
const std::string& query_string,
const std::string& headers,
const std::string& signed_headers,
const std::string& content_sha256);
std::string GetStringToSign(const utils::Time& date, const std::string& scope,
std::string GetStringToSign(const utils::UtcTime& date,
const std::string& scope,
const std::string& canonical_request_hash);
std::string HmacHash(std::string_view key, std::string_view data);
std::string GetSigningKey(const std::string& secret_key,
const utils::Time& date, std::string_view region,
const utils::UtcTime& date, std::string_view region,
std::string_view service_name);
std::string GetSignature(std::string_view signing_key,
std::string_view string_to_sign);
Expand All @@ -48,30 +49,31 @@ utils::Multimap SignV4(const std::string& service_name, http::Method method,
const std::string& access_key,
const std::string& secret_key,
const std::string& content_sha256,
const utils::Time& date);
const utils::UtcTime& date);
utils::Multimap SignV4S3(http::Method method, const std::string& uri,
const std::string& region, utils::Multimap& headers,
utils::Multimap query_params,
const std::string& access_key,
const std::string& secret_key,
const std::string& content_sha256,
const utils::Time& date);
const utils::UtcTime& date);
utils::Multimap SignV4STS(http::Method method, const std::string& uri,
const std::string& region, utils::Multimap& headers,
utils::Multimap query_params,
const std::string& access_key,
const std::string& secret_key,
const std::string& content_sha256,
const utils::Time& date);
const utils::UtcTime& date);
utils::Multimap PresignV4(http::Method method, const std::string& host,
const std::string& uri, const std::string& region,
utils::Multimap query_params,
const std::string& access_key,
const std::string& secret_key,
const utils::Time& date, unsigned int expires);
const utils::UtcTime& date, unsigned int expires);
std::string PostPresignV4(const std::string& data,
const std::string& secret_key,
const utils::Time& date, const std::string& region);
const utils::UtcTime& date,
const std::string& region);
} // namespace signer
} // namespace minio
#endif // #ifndef __MINIO_SIGNER_H
10 changes: 5 additions & 5 deletions include/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ using SelectResultFunction = std::function<bool(SelectResult)>;

struct Bucket {
std::string name;
utils::Time creation_date;
utils::UtcTime creation_date;

Bucket() = default;
~Bucket() = default;
Expand All @@ -316,7 +316,7 @@ struct Bucket {
struct Part {
unsigned int number;
std::string etag;
utils::Time last_modified = {};
utils::UtcTime last_modified = {};
size_t size = 0;

Part() = default;
Expand All @@ -325,7 +325,7 @@ struct Part {

struct Retention {
RetentionMode mode;
utils::Time retain_until_date;
utils::UtcTime retain_until_date;

Retention() = default;
~Retention() = default;
Expand Down Expand Up @@ -687,7 +687,7 @@ struct ReplicationConfig {

struct LifecycleRule {
Integer abort_incomplete_multipart_upload_days_after_initiation;
utils::Time expiration_date;
utils::UtcTime expiration_date;
Integer expiration_days;
Boolean expiration_expired_object_delete_marker;
Filter filter;
Expand All @@ -696,7 +696,7 @@ struct LifecycleRule {
Integer noncurrent_version_transition_noncurrent_days;
std::string noncurrent_version_transition_storage_class;
bool status = false;
utils::Time transition_date;
utils::UtcTime transition_date;
Integer transition_days;
std::string transition_storage_class;

Expand Down
56 changes: 27 additions & 29 deletions include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,69 +118,67 @@ error::Error CalcPartInfo(long object_size, size_t& part_size,
long& part_count);

/**
* Time represents date and time with timezone.
* UtcTime represents date and time in UTC timezone.
*/
class Time {
class UtcTime {
private:
struct timeval tv_ = {};
bool utc_ = false;
std::time_t secs_ = {};
long usecs_ = 0L;

std::tm* getBrokenDownTime() const;

public:
Time() = default;
UtcTime() = default;

Time(std::time_t tv_sec, long tv_usec, bool utc) : utc_(utc) {
tv_.tv_sec = static_cast<decltype(tv_.tv_sec)>(tv_sec);
tv_.tv_usec = static_cast<decltype(tv_.tv_usec)>(tv_usec);
}
UtcTime(std::time_t secs) : secs_(secs) {}
UtcTime(std::time_t secs, long usecs) : secs_(secs), usecs_(usecs) {}

~Time() = default;
~UtcTime() = default;

void Add(std::time_t seconds) {
tv_.tv_sec += static_cast<decltype(tv_.tv_sec)>(seconds);
}
void Add(std::time_t seconds) { secs_ += seconds; }

std::tm* ToUTC() const;
void ToLocalTime(std::tm& time);

std::string ToSignerDate() const;

std::string ToAmzDate() const;

std::string ToHttpHeaderValue() const;

static Time FromHttpHeaderValue(const char* value);
static UtcTime FromHttpHeaderValue(const char* value);

std::string ToISO8601UTC() const;

static Time FromISO8601UTC(const char* value);
static UtcTime FromISO8601UTC(const char* value);

static Time Now();
static UtcTime Now();

explicit operator bool() const { return tv_.tv_sec != 0 && tv_.tv_usec != 0; }
explicit operator bool() const { return secs_ != 0 && usecs_ != 0; }

int Compare(const Time& rhs) const;
int Compare(const UtcTime& rhs) const;

bool Equal(const Time& rhs) const { return Compare(rhs) == 0; }
bool Equal(const UtcTime& rhs) const { return Compare(rhs) == 0; }

bool operator==(const Time& rhs) const { return Equal(rhs); }
bool operator==(const UtcTime& rhs) const { return Equal(rhs); }

bool operator!=(const Time& rhs) const { return !operator==(rhs); }
bool operator!=(const UtcTime& rhs) const { return !operator==(rhs); }

bool operator<(const Time& rhs) const { return Compare(rhs) < 0; }
bool operator<(const UtcTime& rhs) const { return Compare(rhs) < 0; }

bool operator>(const Time& rhs) const { return Compare(rhs) > 0; }
bool operator>(const UtcTime& rhs) const { return Compare(rhs) > 0; }

bool operator<=(const Time& rhs) const { return !operator>(rhs); }
bool operator<=(const UtcTime& rhs) const { return !operator>(rhs); }

bool operator>=(const Time& rhs) const { return !operator<(rhs); }
bool operator>=(const UtcTime& rhs) const { return !operator<(rhs); }

#if __cplusplus >= 202002L
auto operator<=>(const Time& rhs) const { return Compare(rhs); }
auto operator<=>(const UtcTime& rhs) const { return Compare(rhs); }
#endif

friend std::ostream& operator<<(std::ostream& s, const Time& v) {
friend std::ostream& operator<<(std::ostream& s, const UtcTime& v) {
return s << v.ToISO8601UTC();
}
}; // class Time
}; // class UtcTime

/**
* Multimap represents dictionary of keys and their multiple values.
Expand Down
4 changes: 2 additions & 2 deletions src/args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ minio::error::Error minio::s3::PostPolicy::FormData(
conditions.push_back(
{"content-length-range", lower_limit_.Get(), upper_limit_.Get()});
}
utils::Time date = utils::Time::Now();
utils::UtcTime date = utils::UtcTime::Now();
std::string credential = getCredentialString(access_key, date, region);
std::string amz_date = date.ToAmzDate();
conditions.push_back({eq_, "$x-amz-algorithm", algorithm_});
Expand Down Expand Up @@ -692,7 +692,7 @@ std::string minio::s3::PostPolicy::trimDollar(std::string value) {
}

std::string minio::s3::PostPolicy::getCredentialString(std::string access_key,
utils::Time date,
utils::UtcTime date,
std::string region) {
return access_key + "/" + date.ToSignerDate() + "/" + region +
"/s3/aws4_request";
Expand Down
9 changes: 5 additions & 4 deletions src/baseclient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,8 @@ minio::s3::GetObjectRetentionResponse minio::s3::BaseClient::GetObjectRetention(
response.retention_mode = StringToRetentionMode(text.node().value());

text = xdoc.select_node("/Retention/RetainUntilDate/text()");
response.retain_until_date = utils::Time::FromISO8601UTC(text.node().value());
response.retain_until_date =
utils::UtcTime::FromISO8601UTC(text.node().value());

return response;
}
Expand Down Expand Up @@ -933,7 +934,7 @@ minio::s3::BaseClient::GetPresignedObjectUrl(GetPresignedObjectUrlArgs args) {
query_params.Add("X-Amz-Security-Token", creds.session_token);
}

utils::Time date = utils::Time::Now();
utils::UtcTime date = utils::UtcTime::Now();
if (args.request_time) date = args.request_time;

std::string host = url.HostHeaderValue();
Expand Down Expand Up @@ -1704,7 +1705,7 @@ minio::s3::StatObjectResponse minio::s3::BaseClient::StatObject(

value = response.headers.GetFront("last-modified");
if (!value.empty()) {
resp.last_modified = utils::Time::FromHttpHeaderValue(value.c_str());
resp.last_modified = utils::UtcTime::FromHttpHeaderValue(value.c_str());
}

value = response.headers.GetFront("x-amz-object-lock-mode");
Expand All @@ -1713,7 +1714,7 @@ minio::s3::StatObjectResponse minio::s3::BaseClient::StatObject(
value = response.headers.GetFront("x-amz-object-lock-retain-until-date");
if (!value.empty()) {
resp.retention_retain_until_date =
utils::Time::FromISO8601UTC(value.c_str());
utils::UtcTime::FromISO8601UTC(value.c_str());
}

value = response.headers.GetFront("x-amz-object-lock-legal-hold");
Expand Down
Loading

0 comments on commit c43db14

Please sign in to comment.