Skip to content

Commit

Permalink
the safe credentials manager lands on GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
apolloakora committed Feb 11, 2019
1 parent 105dff9 commit 053b401
Show file tree
Hide file tree
Showing 87 changed files with 14,217 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
3 changes: 3 additions & 0 deletions .yardopts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--title "opensecret credentials manager"
lib/**/*.rb -
lib/**/*.ini
10 changes: 10 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## ============================================
## Try removing this file
## See what happens
## ============================================
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# Specify your gem's dependencies in safedb.gemspec
gemspec
793 changes: 793 additions & 0 deletions README.md

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require "bundler/gem_tasks"
require "rake/testtask"

# -
# - This configuration allows us to run "rake test"
# - and invoke minitest to execute all files in the
# - test directory with names ending in "_test.rb".
# -
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/*_test.rb"]
end

task :default => :test

5 changes: 5 additions & 0 deletions bin/safedb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby

require 'interprete'

Interprete.start(ARGV)
58 changes: 58 additions & 0 deletions lib/configs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

# Modifying Safe's Behaviour | 4 Configuration Scopes

Safe's behaviour can (by default) be modified in a manner that is scoped in 4 ways. Configuration directives can alter behaviour within

1. a **book global** scope
2. a **machine local** scope
3. a **shell session** scope and
4. a **machine global** scope

The scoping concept is similar to Git's --local and --global but it works in a different way.


## 1. Book Global Scope

Directives issued against a safe book **"feel local"** but are global in that the behaviour persists on every machine that works with the book.

Git's --local is different because cloning the repository on another machine wipe's out the directives. With safe the directives continue to alter behaviour even when the book is cloned and/or used on another machine.


## 2. Machine Local Scope

This is similar to Git's --global directive which affects all repositories owned by a user on a given machine.

Directives with a machine local scope **can influence the behaviour** of every Safe book one logs into on a machine. Move to another machine and the behaviour becomes unstuck.

== Configuration Directive Precedence

Note the sentence **can influence behaviour** as opposed to **will influence behaviour**.

If a directive with a book global scope says "Yes" and the same directive exists but says "No" with machine local scope the "Yes" wins out.

A book global directive overrides its machine local twin.


## 3. Shell Session Scope

The self explanatory **shell session scoped** directives override their siblings be they book global or machine local.

Alas, their elevated privileges are countered by relatively short lifespans. Shell session directives only last until either a logout is issued or the shell session comes to an end.


## 4. Default | Machine Global Scope

Did you notice only **one (1) user** is affected by directives with a machine local scope as long as it isn't overriden.

Directives with a **machine global scope** are the **default** and are set during an install or upgrade.

They can potentially affect **every user and every safe book**. Even though their longevity is undisputed, their precedence is the lowest when going head to head with their 3 siblings.

## The Naked Eye

Directives with a book global scope **aren't visible to the naked eye**. They are encrypted within the master safe database and thus protected from prying eyes.

The other 3 directive types exist in plain text

- either where the gem is **installed** (machine global scope)
- or in the INI file in **.safe** off the user's home directory
162 changes: 162 additions & 0 deletions lib/extension/array.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/usr/bin/ruby

#
# Reopen the core ruby Array class and add the below methods to it.
#
# Case Sensitivity rules for [ALL] the below methods that are
# added to the core Ruby string class.
#
# For case insensitive behaviour make sure you downcase both the
# string object and the parameter strings (or strings within
# other parameter objects, like arrays and hashes).
class Array


# The returned string is a result of a union (join) of all the
# (expected) string array elements followed by the <b>deletion</b>
# of <b>all <em>non</em> alphanumeric characters</b>.
#
# <b>Disambiguating the String for Cross Platform Use</b>
#
# This behaviour is typically used for transforming text that is
# about to be signed or digested (hashed). Removing all the non
# alpha-numeric characters disambiguates the string.
#
# An example is the exclusion of line ending characters which in
# Windows are different from Linux.
#
# This disambiguation means that signing functions will return the
# same result on widely variant platfoms like Windows vs CoreOS.
#
# @return [String]
# Returns the alphanumeric union of the strings within this array.
#
# @raise [ArgumentError]
# if the array is nil or empty. Also an error will be thrown if
# the array contains objects that cannot be naturally converted
# to a string.
def alphanumeric_union
raise ArgumentError, "Cannot do alphanumeric union on an empty array." if self.empty?
return self.join.to_alphanumeric
end


# Log the array using our logging mixin by printing every array
# item into its own log line. In most cases we (the array) are
# a list of strings, however if not, each item's to_string method
# is invoked and the result printed using one log line.
#
# The INFO log level is used to log the lines - if this is not
# appropriate create a (level) parameterized log lines method.
def log_lines

self.each do |line|
clean_line = line.to_s.chomp.gsub("\\n","")
log.info(x) { line } if clean_line.length > 0
end

end


# Get the text [in between] this and that delimeter [exclusively].
# Exclusively means the returned text [does not] include either of
# the matched delimeters (although an unmatched instance of [this]
# delimeter may appear in the in-between text).
#
# --------------------
# Multiple Delimiters
# --------------------
#
# When multiple delimiters exist, the text returned is in between the
#
# [a] - first occurrence of [this] delimeter AND the
# [b] - 1st occurrence of [that] delimeter [AFTER] the 1st delimiter
#
# Instances of [that] delimiter occurring before [this] are ignored.
# The text could contain [this] delimeter instances but is guaranteed
# not to contain a [that] delimeter.
#
# -----------
# Parameters
# -----------
#
# this_delimiter : begin delimeter (not included in returned string)
# that_delimiter : end delimeter (not included in returned string)
#
# -----------
# Exceptions
# -----------
#
# An exception (error) will be thrown if
#
# => any nil (or empties) exist in the input parameters
# => [this] delimeter does not appear in the in_string
# => [that] delimeter does not appear after [this] one
#
def before_and_after begin_delimeter, end_delimeter

Throw.if_nil_or_empty_strings [ self, begin_delimeter, end_delimeter ]

before_after_lines = []
in_middle_bit = false

self.each do |candidate_line|

is_middle_boundary = !in_middle_bit && candidate_line.downcase.include?(begin_delimeter.downcase)
if is_middle_boundary
in_middle_bit = true
next
end

unless in_middle_bit
before_after_lines.push candidate_line
next
end

#--
#-- Now we are definitely in the middle bit.
#-- Let's check for the middle end delimeter
#--
if candidate_line.downcase.include? end_delimeter.downcase
in_middle_bit = false
end

end

return before_after_lines

end


def middlle_bit begin_delimeter, end_delimeter

Throw.if_nil_or_empty_strings [ self, begin_delimeter, end_delimeter ]

middle_lines = []
in_middle_bit = false

self.each do |candidate_line|

is_middle_boundary = !in_middle_bit && candidate_line.downcase.include?(begin_delimeter.downcase)
if is_middle_boundary
in_middle_bit = true
next
end

end_of_middle = in_middle_bit && candidate_line.downcase.include?(end_delimeter.downcase)
return middle_lines if end_of_middle

#--
#-- We are definitely in the middle bit.
#--
middle_lines.push(candidate_line) if in_middle_bit

end

unreachable_str = "This point should be unreachable unless facts are ended."
raise RuntimeError.new unreachable_str

end


end
35 changes: 35 additions & 0 deletions lib/extension/dir.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/ruby

# --
# -- Reopen the core ruby Dirctory class and add the below methods to it.
# --
class Dir

# --
# -- Put all the files starting with the given string in
# -- alphabetical ascending order and then return the file
# -- that comes last.
# --
# -- Throw an exception if no file in this folder starts
# -- with the given string
# --
def ascii_order_file_starting_with starts_with_string

recently_added_file = nil
filepath_leadstr = File.join self.path, starts_with_string
Dir.glob("#{filepath_leadstr}*").sort.each do |candidate_file|

next if File.directory? candidate_file
recently_added_file = candidate_file

end

Throw.if_nil recently_added_file
Throw.if_not_exists recently_added_file
return recently_added_file

end



end
Loading

0 comments on commit 053b401

Please sign in to comment.