
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
This gem is an unofficial set of Ruby bindings for the Timestamp API.
Add this line to your application's Gemfile:
gem "timestamp_api"
And then execute:
$ bundle
Or install it yourself as:
$ gem install timestamp_api
Configure your Timestamp API key by setting environment variable TIMESTAMP_API_KEY
:
$ TIMESTAMP_API_KEY="YOUR_API_KEY" bin/console
Or set it manually from the console:
TimestampAPi.api_key = "YOUR_API_KEY"
List clients:
TimestampAPI::Client.all # => Returns all clients
Find a given client:
client = TimestampAPI::Client.find(123)
client.name # => "My beloved customer"
List projects:
TimestampAPI::Project.all # => Returns all projects
Find a given project:
project = TimestampAPI::Project.find(123)
project.name # => "My awesome project"
project.client.name # => "My beloved customer"
project.enter_time(123, Date.today, 60) # => Creates a 60 minutes time entry for today on task 123 and returns the created TimeEntry
List users:
TimestampAPI::User.all # => Returns all users
Find a given user:
user = TimestampAPI::User.find(123)
user.full_name # => "Great developer"
List tasks:
TimestampAPI::Task.all # => Returns all tasks
TimestampAPI::Task.for_project_id(123) # => Returns tasks for project 123
Find a given task:
task = TimestampAPI::Task.find(123)
task.name # => "My fantastic task"
task.project.name # => "My awesome project"
List time entries:
TimestampAPI::TimeEntry.all # => Returns all time entries
TimestampAPI::TimeEntry.for_task_id(123) # => Returns time entries for task 123
Find a given time entry:
time_entry = TimestampAPI::TimeEntry.find(123)
time_entry.comment # => "Stuff got done"
time_entry.client.name # => "My beloved customer"
time_entry.project.name # => "My awesome project"
time_entry.task.name # => "My fantastic task"
time_entry.user.full_name # => "Great developer"
List events:
TimestampAPI::Event.all # => Returns all events
Find a given event:
event = TimestampAPI::Event.find(123)
event.object # => Returns the object on which event occured
The objects are represented by model classes (that inherits from TimestampAPI::Model
):
project = TimestampAPI::Project.find(123456)
project.class # => TimestampAPI::Project
project.is_a? TimestampAPI::Model # => true
Collections of objects are represented by TimestampAPI::Collection
that inherits from Array
(and implement the chainable .where(conditions)
filter method described above). It means any Array
method works on TimestampAPI::Collection
:
projects = TimestampAPI::Project.all
projects.class # => TimestampAPI::Collection
projects.map(&:name) # => ["A project", "Another project", "One more project"]
Models can can bound together and are accessible using a simple getter:
Exemple: find the client bound to a project:
project = TimestampAPI::Project.find(123)
project.client.name # => "My beloved customer"
:information_source: First call to such a relation getter will trigger an API request and memoize the response for network optimization.
You can filter any object collection using the handy .where()
syntax:
projects = TimestampAPI::Project.all
projects.where(is_public: true) # => returns all public projects
projects.where(is_public: true, is_billable: true) # => returns all projects that are both public and billable
projects.where(is_public: true).where(is_billable: true) # => same as above: `where` is chainable \o/
:information_source: This does not filter objects before the network call (like ActiveRecord does), it's only a more elegant way of calling Array#select
on the Collection
The above methods are simple wrappers around the generic low-level-ish API request method TimestampAPI.request
that take a HTTP method
(verb) and a path
(to be appended to preconfigured API endpoint URL):
TimestampAPI.request(:get, "/projects") # Same as TimestampAPI::Project.all
TimestampAPI.request(:get, "/projects/123456") # Same as TimestampAPI::Project.find(123456)
To output all network requests done, you can set verbosity on:
TimestampAPI.verbose = true
As the API is not documented nor even officially supported by Timestamp, we're trying to reverse-engineer it.
:warning: This means that Timestamp can introduce breaking changes within their API without prior notice at any time (and thus break this gem).
It also means that if you're willing to hack into it with us, you're very welcome :+1:
While logged in, the Timestamp API data can be explored from your favourite browser (with a JSON viewer addon, if needed) here: https://api.ontimestamp.com/api
There's also a bin/console
executable provided with this gem, if you want a REPL to hack around.
Project
modelClient
modelTask
modelUser
model (their roles
could be enhanced, though)TimeEntry
modelEvent
modelbelongs_to
relationshipshas_many
relationshipsAfter checking out the repo, run bin/setup
to install dependencies. Then, run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
to create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)This code is distributed by Alpine Lab under the terms of the MIT license.
See LICENCE.md
FAQs
Unknown package
We found that timestamp_api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.