htauth 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/HISTORY.md +7 -0
- data/Manifest.txt +4 -0
- data/README.md +36 -22
- data/Rakefile +8 -4
- data/lib/htauth.rb +1 -0
- data/lib/htauth/algorithm.rb +32 -29
- data/lib/htauth/bcrypt.rb +35 -0
- data/lib/htauth/cli/digest.rb +1 -1
- data/lib/htauth/cli/passwd.rb +90 -30
- data/lib/htauth/console.rb +5 -1
- data/lib/htauth/crypt.rb +15 -4
- data/lib/htauth/descendant_tracker.rb +46 -0
- data/lib/htauth/md5.rb +27 -7
- data/lib/htauth/passwd_entry.rb +22 -17
- data/lib/htauth/passwd_file.rb +46 -12
- data/lib/htauth/plaintext.rb +11 -4
- data/lib/htauth/sha1.rb +8 -5
- data/lib/htauth/version.rb +1 -1
- data/spec/algorithm_spec.rb +8 -0
- data/spec/bcrypt_spec.rb +33 -0
- data/spec/cli/digest_spec.rb +22 -23
- data/spec/cli/passwd_spec.rb +160 -36
- data/spec/crypt_spec.rb +1 -5
- data/spec/digest_entry_spec.rb +19 -19
- data/spec/digest_file_spec.rb +10 -10
- data/spec/md5_spec.rb +1 -5
- data/spec/passwd_entry_spec.rb +63 -42
- data/spec/passwd_file_spec.rb +31 -13
- data/spec/plaintext_spec.rb +1 -5
- data/spec/sha1_spec.rb +1 -5
- data/tasks/default.rake +3 -3
- data/tasks/this.rb +2 -2
- metadata +32 -13
    
        data/spec/passwd_entry_spec.rb
    CHANGED
    
    | @@ -9,130 +9,151 @@ describe HTAuth::PasswdEntry do | |
| 9 9 | 
             
              end
         | 
| 10 10 |  | 
| 11 11 | 
             
              it "initializes with a user and realm" do
         | 
| 12 | 
            -
                @alice.user.must_equal "alice"
         | 
| 12 | 
            +
                _(@alice.user).must_equal "alice"
         | 
| 13 13 | 
             
              end
         | 
| 14 14 |  | 
| 15 15 | 
             
              it "has the correct crypt password" do
         | 
| 16 16 | 
             
                @alice.password = "a secret"
         | 
| 17 | 
            -
                @alice.digest.must_equal "mDwdZuXalQ5zk"
         | 
| 17 | 
            +
                _(@alice.digest).must_equal "mDwdZuXalQ5zk"
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 20 | 
             
              it "encrypts correctly for md5" do
         | 
| 21 21 | 
             
                bob = HTAuth::PasswdEntry.new("bob", "b secret", "md5", { :salt => @salt })
         | 
| 22 | 
            -
                bob.digest.must_equal "$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1"
         | 
| 22 | 
            +
                _(bob.digest).must_equal "$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1"
         | 
| 23 23 | 
             
              end
         | 
| 24 24 |  | 
| 25 25 | 
             
              it "encrypts correctly for sha1" do
         | 
| 26 26 | 
             
                bob = HTAuth::PasswdEntry.new("bob", "b secret", "sha1", { :salt => @salt })
         | 
| 27 | 
            -
                bob.digest.must_equal "{SHA}b/tjGXbX80MEKVnF200S43ca4hY="
         | 
| 27 | 
            +
                _(bob.digest).must_equal "{SHA}b/tjGXbX80MEKVnF200S43ca4hY="
         | 
| 28 28 | 
             
              end
         | 
| 29 29 |  | 
| 30 30 | 
             
              it "encrypts correctly for plaintext" do
         | 
| 31 31 | 
             
                bob = HTAuth::PasswdEntry.new("bob", "b secret", "plaintext", { :salt => @salt })
         | 
| 32 | 
            -
                bob.digest.must_equal "b secret"
         | 
| 32 | 
            +
                _(bob.digest).must_equal "b secret"
         | 
| 33 33 | 
             
              end
         | 
| 34 34 |  | 
| 35 35 | 
             
              it "encrypts with crypt as a default, when parsed from crypt()'d line" do
         | 
| 36 36 | 
             
                bob2 = HTAuth::PasswdEntry.from_line(@bob.to_s)
         | 
| 37 | 
            -
                bob2.algorithm.must_be_instance_of( | 
| 38 | 
            -
                bob2.algorithm.size.must_equal 2
         | 
| 37 | 
            +
                _(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
         | 
| 39 38 | 
             
                bob2.password = "another secret"
         | 
| 40 | 
            -
                bob2.algorithm.must_be_instance_of(HTAuth::Crypt)
         | 
| 39 | 
            +
                _(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
         | 
| 41 40 | 
             
              end
         | 
| 42 41 |  | 
| 43 42 | 
             
              it "encrypts with crypt as a default, when parsed from plaintext line" do
         | 
| 44 43 | 
             
                p = HTAuth::PasswdEntry.new('paul', 'p secret', 'plaintext')
         | 
| 45 44 | 
             
                p2 = HTAuth::PasswdEntry.from_line(p.to_s)
         | 
| 46 | 
            -
                p2.algorithm.must_be_instance_of( | 
| 47 | 
            -
                p2.algorithm.size.must_equal 2
         | 
| 45 | 
            +
                _(p2.algorithm).must_be_instance_of(HTAuth::Plaintext)
         | 
| 48 46 | 
             
                p2.password = "another secret"
         | 
| 49 | 
            -
                p2.algorithm.must_be_instance_of(HTAuth::Crypt)
         | 
| 47 | 
            +
                _(p2.algorithm).must_be_instance_of(HTAuth::Crypt)
         | 
| 50 48 | 
             
              end
         | 
| 51 49 |  | 
| 52 50 | 
             
              it "encrypts with md5 as default, when parsed from an md5 line" do
         | 
| 53 51 | 
             
                m = HTAuth::PasswdEntry.new("mary", "m secret", "md5") 
         | 
| 54 52 | 
             
                m2 = HTAuth::PasswdEntry.from_line(m.to_s)
         | 
| 55 | 
            -
                m2.algorithm.must_be_instance_of(HTAuth::Md5)
         | 
| 53 | 
            +
                _(m2.algorithm).must_be_instance_of(HTAuth::Md5)
         | 
| 56 54 | 
             
              end
         | 
| 57 55 |  | 
| 58 56 | 
             
              it "encrypts with sha1 as default, when parsed from an sha1 line" do
         | 
| 59 57 | 
             
                s = HTAuth::PasswdEntry.new("steve", "s secret", "sha1") 
         | 
| 60 58 | 
             
                s2 = HTAuth::PasswdEntry.from_line(s.to_s)
         | 
| 61 | 
            -
                s2.algorithm.must_be_instance_of(HTAuth::Sha1)
         | 
| 59 | 
            +
                _(s2.algorithm).must_be_instance_of(HTAuth::Sha1)
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              it "encrypts with bcrypt as default when parsed from a bcrypt line" do
         | 
| 63 | 
            +
                b = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
         | 
| 64 | 
            +
                b2 = HTAuth::PasswdEntry.from_line(b.to_s)
         | 
| 65 | 
            +
                _(b2.algorithm).must_be_instance_of(HTAuth::Bcrypt)
         | 
| 62 66 | 
             
              end
         | 
| 63 67 |  | 
| 64 68 | 
             
              it "determins the algorithm to be crypt when checking a password" do
         | 
| 65 69 | 
             
                bob2 = HTAuth::PasswdEntry.from_line(@bob.to_s)
         | 
| 66 | 
            -
                bob2.algorithm.must_be_instance_of( | 
| 67 | 
            -
                bob2. | 
| 68 | 
            -
                bob2. | 
| 69 | 
            -
                bob2.algorithm.must_be_instance_of(HTAuth::Crypt)
         | 
| 70 | 
            +
                _(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
         | 
| 71 | 
            +
                _(bob2.authenticated?("b secret")).must_equal true
         | 
| 72 | 
            +
                _(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
         | 
| 70 73 | 
             
              end
         | 
| 71 74 |  | 
| 72 75 | 
             
              it "determins the algorithm to be plain when checking a password" do
         | 
| 73 76 | 
             
                bob2 = HTAuth::PasswdEntry.from_line("bob:b secret")
         | 
| 74 | 
            -
                bob2.algorithm.must_be_instance_of( | 
| 75 | 
            -
                bob2. | 
| 76 | 
            -
                bob2. | 
| 77 | 
            -
                bob2.algorithm.must_be_instance_of(HTAuth::Plaintext)
         | 
| 77 | 
            +
                _(bob2.algorithm).must_be_instance_of(HTAuth::Plaintext)
         | 
| 78 | 
            +
                _(bob2.authenticated?("b secret")).must_equal true
         | 
| 79 | 
            +
                _(bob2.algorithm).must_be_instance_of(HTAuth::Plaintext)
         | 
| 78 80 | 
             
              end
         | 
| 79 81 |  | 
| 80 82 | 
             
              it "authenticates correctly against md5" do
         | 
| 81 83 | 
             
                m = HTAuth::PasswdEntry.new("mary", "m secret", "md5") 
         | 
| 82 84 | 
             
                m2 = HTAuth::PasswdEntry.from_line(m.to_s)
         | 
| 83 | 
            -
                m2.authenticated?("m secret").must_equal true
         | 
| 85 | 
            +
                _(m2.authenticated?("m secret")).must_equal true
         | 
| 84 86 | 
             
              end
         | 
| 85 87 |  | 
| 86 88 | 
             
              it "authenticates correctly against sha1" do
         | 
| 87 89 | 
             
                s = HTAuth::PasswdEntry.new("steve", "s secret", "sha1") 
         | 
| 88 90 | 
             
                s2 = HTAuth::PasswdEntry.from_line(s.to_s)
         | 
| 89 | 
            -
                s2.authenticated?("s secret").must_equal true
         | 
| 91 | 
            +
                _(s2.authenticated?("s secret")).must_equal true
         | 
| 92 | 
            +
              end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              it "authenticates correctly against bcrypt" do
         | 
| 95 | 
            +
                s = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
         | 
| 96 | 
            +
                s2 = HTAuth::PasswdEntry.from_line(s.to_s)
         | 
| 97 | 
            +
                _(s2.authenticated?("b secret")).must_equal true
         | 
| 90 98 | 
             
              end
         | 
| 91 99 |  | 
| 100 | 
            +
              it "can update the cost of an entry after initialization before encoding password" do
         | 
| 101 | 
            +
                s = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
         | 
| 102 | 
            +
                _(s.algorithm.cost).must_equal(::HTAuth::Bcrypt::DEFAULT_APACHE_COST)
         | 
| 92 103 |  | 
| 104 | 
            +
                s2 = HTAuth::PasswdEntry.from_line(s.to_s)
         | 
| 105 | 
            +
                s2.algorithm_args = { :cost => 12 }
         | 
| 106 | 
            +
                s2.password = "b secret" # forces recalculation
         | 
| 93 107 |  | 
| 108 | 
            +
                _(s2.algorithm.cost).must_equal(12)
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              it "raises an error if assinging an invalid algorithm" do
         | 
| 112 | 
            +
                b = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
         | 
| 113 | 
            +
                _ { b.algorithm = 42 }.must_raise(HTAuth::InvalidAlgorithmError)
         | 
| 114 | 
            +
              end
         | 
| 94 115 |  | 
| 95 116 | 
             
              it "returns username for a key" do
         | 
| 96 | 
            -
                @alice.key.must_equal "alice"
         | 
| 117 | 
            +
                _(@alice.key).must_equal "alice"
         | 
| 97 118 | 
             
              end
         | 
| 98 119 |  | 
| 99 120 | 
             
              it "checks the password correctly" do
         | 
| 100 | 
            -
                @bob.authenticated?("b secret").must_equal true
         | 
| 121 | 
            +
                _(@bob.authenticated?("b secret")).must_equal true
         | 
| 101 122 | 
             
              end
         | 
| 102 123 |  | 
| 103 124 | 
             
              it "formats correctly when put to a string" do
         | 
| 104 | 
            -
                @bob.to_s.must_equal "bob:b8Ml4Jp9I0N8E"
         | 
| 125 | 
            +
                _(@bob.to_s).must_equal "bob:b8Ml4Jp9I0N8E"
         | 
| 105 126 | 
             
              end
         | 
| 106 127 |  | 
| 107 128 | 
             
              it "parses an input line" do
         | 
| 108 129 | 
             
                @bob_new = HTAuth::PasswdEntry.from_line("bob:b8Ml4Jp9I0N8E")
         | 
| 109 | 
            -
                @bob.user.must_equal @bob_new.user
         | 
| 110 | 
            -
                @bob.digest.must_equal @bob_new.digest
         | 
| 130 | 
            +
                _(@bob.user).must_equal @bob_new.user
         | 
| 131 | 
            +
                _(@bob.digest).must_equal @bob_new.digest
         | 
| 111 132 | 
             
              end
         | 
| 112 133 |  | 
| 113 134 | 
             
              it "knows if an input line is a possible entry and raises an exception" do
         | 
| 114 | 
            -
                 | 
| 115 | 
            -
                 | 
| 116 | 
            -
                 | 
| 117 | 
            -
                 | 
| 135 | 
            +
                _ { HTAuth::PasswdEntry.is_entry!("#stuff") }.must_raise(HTAuth::InvalidPasswdEntry)
         | 
| 136 | 
            +
                _ { HTAuth::PasswdEntry.is_entry!("this:that:other:stuff") }.must_raise(HTAuth::InvalidPasswdEntry)
         | 
| 137 | 
            +
                _ { HTAuth::PasswdEntry.is_entry!("this:that:other") }.must_raise(HTAuth::InvalidPasswdEntry)
         | 
| 138 | 
            +
                _ { HTAuth::PasswdEntry.is_entry!("this:that:0a90549e8ffb2dd62f98252a95d88xyz") }.must_raise(HTAuth::InvalidPasswdEntry)
         | 
| 118 139 | 
             
              end
         | 
| 119 140 |  | 
| 120 141 | 
             
              it "knows if an input line is a possible entry and returns false" do
         | 
| 121 | 
            -
                HTAuth::PasswdEntry.is_entry?("#stuff").must_equal false
         | 
| 122 | 
            -
                HTAuth::PasswdEntry.is_entry?("this:that:other:stuff").must_equal false 
         | 
| 123 | 
            -
                HTAuth::PasswdEntry.is_entry?("this:that:other").must_equal false 
         | 
| 124 | 
            -
                HTAuth::PasswdEntry.is_entry?("this:that:0a90549e8ffb2dd62f98252a95d88xyz").must_equal false
         | 
| 142 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("#stuff")).must_equal false
         | 
| 143 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("this:that:other:stuff")).must_equal false 
         | 
| 144 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("this:that:other")).must_equal false 
         | 
| 145 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("this:that:0a90549e8ffb2dd62f98252a95d88xyz")).must_equal false
         | 
| 125 146 | 
             
              end
         | 
| 126 147 |  | 
| 127 148 | 
             
              it "knows if an input line is a possible entry and returns true" do
         | 
| 128 | 
            -
                HTAuth::PasswdEntry.is_entry?("bob:irRm0g.SDfCyI").must_equal true
         | 
| 129 | 
            -
                HTAuth::PasswdEntry.is_entry?("bob:b secreat").must_equal true
         | 
| 130 | 
            -
                HTAuth::PasswdEntry.is_entry?("bob:{SHA}b/tjGXbX80MEKVnF200S43ca4hY=").must_equal true
         | 
| 131 | 
            -
                HTAuth::PasswdEntry.is_entry?("bob:$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1").must_equal true
         | 
| 132 | 
            -
             | 
| 149 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("bob:irRm0g.SDfCyI")).must_equal true
         | 
| 150 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("bob:b secreat")).must_equal true
         | 
| 151 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("bob:{SHA}b/tjGXbX80MEKVnF200S43ca4hY=")).must_equal true
         | 
| 152 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("bob:$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1")).must_equal true
         | 
| 153 | 
            +
                _(HTAuth::PasswdEntry.is_entry?("bob:$2y$05$ts3k1r.t0Cne6j6DLt0/SepT5X4qthDFEdfqHBBMO5MhqzyMz34j2")).must_equal true
         | 
| 133 154 | 
             
              end
         | 
| 134 155 |  | 
| 135 156 | 
             
              it "duplicates itself" do
         | 
| 136 | 
            -
                @alice.dup.to_s.must_equal @alice.to_s
         | 
| 157 | 
            +
                _(@alice.dup.to_s).must_equal @alice.to_s
         | 
| 137 158 | 
             
              end
         | 
| 138 159 | 
             
            end
         | 
    
        data/spec/passwd_file_spec.rb
    CHANGED
    
    | @@ -22,45 +22,63 @@ describe HTAuth::PasswdFile do | |
| 22 22 |  | 
| 23 23 | 
             
              it "can add a new entry to an already existing passwd file" do
         | 
| 24 24 | 
             
                @passwd_file.add_or_update("charlie", "c secret", "sha1")
         | 
| 25 | 
            -
                @passwd_file.contents.must_equal IO.read(PASSWD_ADD_TEST_FILE)
         | 
| 25 | 
            +
                _(@passwd_file.contents).must_equal IO.read(PASSWD_ADD_TEST_FILE)
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| 28 28 | 
             
              it "can tell if an entry already exists in the passwd file" do
         | 
| 29 | 
            -
                @passwd_file.has_entry?("alice").must_equal true
         | 
| 30 | 
            -
                @passwd_file.has_entry?("david").must_equal false
         | 
| 29 | 
            +
                _(@passwd_file.has_entry?("alice")).must_equal true
         | 
| 30 | 
            +
                _(@passwd_file.has_entry?("david")).must_equal false
         | 
| 31 31 | 
             
              end
         | 
| 32 32 |  | 
| 33 33 | 
             
              it "can update an entry in an already existing passwd file, algorithm can change" do
         | 
| 34 34 | 
             
                @passwd_file.add_or_update("alice", "a new secret", "sha1")
         | 
| 35 | 
            -
                @passwd_file.contents.must_equal IO.read(PASSWD_UPDATE_TEST_FILE)
         | 
| 35 | 
            +
                _(@passwd_file.contents).must_equal IO.read(PASSWD_UPDATE_TEST_FILE)
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              it "can update an entry in an already existing passwd file, algorithm and arguments can change" do
         | 
| 39 | 
            +
                @passwd_file.add_or_update("brenda", "b secret", "bcrypt")
         | 
| 40 | 
            +
                entry = @passwd_file.fetch("brenda")
         | 
| 41 | 
            +
                _(entry.algorithm.cost).must_equal(::HTAuth::Bcrypt::DEFAULT_APACHE_COST)
         | 
| 42 | 
            +
                @passwd_file.add_or_update("brenda", "b secret", "bcrypt", :cost => 12)
         | 
| 43 | 
            +
                entry = @passwd_file.fetch("brenda")
         | 
| 44 | 
            +
                _(entry.algorithm.cost).must_equal(12)
         | 
| 36 45 | 
             
              end
         | 
| 37 46 |  | 
| 38 47 | 
             
              it "fetches a copy of an entry" do
         | 
| 39 | 
            -
                @passwd_file.fetch("alice").to_s.must_equal "alice:$apr1$DghnA...$CsPcgerfsI/Ryy0AOAJtb0"
         | 
| 48 | 
            +
                _(@passwd_file.fetch("alice").to_s).must_equal "alice:$apr1$DghnA...$CsPcgerfsI/Ryy0AOAJtb0"
         | 
| 40 49 | 
             
              end
         | 
| 41 50 |  | 
| 42 | 
            -
              it "raises an error if an attempt is made to alter a non- | 
| 43 | 
            -
                 | 
| 51 | 
            +
              it "raises an error if an attempt is made to alter a non-existent file" do
         | 
| 52 | 
            +
                _ { HTAuth::PasswdFile.new("some-file") }.must_raise(HTAuth::FileAccessError)
         | 
| 44 53 | 
             
              end
         | 
| 45 54 |  | 
| 46 55 | 
             
              # this test will only work on systems that have /etc/ssh_host_rsa_key 
         | 
| 47 56 | 
             
              it "raises an error if an attempt is made to open a file where no permissions are granted" do
         | 
| 48 | 
            -
                 | 
| 57 | 
            +
                _ { HTAuth::PasswdFile.new("/etc/ssh_host_rsa_key") }.must_raise(HTAuth::FileAccessError)
         | 
| 49 58 | 
             
              end
         | 
| 50 59 |  | 
| 51 60 | 
             
              it "deletes an entry" do
         | 
| 52 61 | 
             
                @passwd_file.delete("bob")
         | 
| 53 | 
            -
                @passwd_file.contents.must_equal IO.read(PASSWD_DELETE_TEST_FILE)
         | 
| 62 | 
            +
                _(@passwd_file.contents).must_equal IO.read(PASSWD_DELETE_TEST_FILE)
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              it "checks authentication of an entry - true" do
         | 
| 66 | 
            +
                _(@passwd_file.authenticated?("alice", "a secret")).must_equal true
         | 
| 54 67 | 
             
              end
         | 
| 55 68 |  | 
| 56 | 
            -
              it " | 
| 69 | 
            +
              it "checks authentication of an entry - false" do
         | 
| 70 | 
            +
                _(@passwd_file.authenticated?("alice", "the wrong secret")).must_equal false
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
             | 
| 74 | 
            +
              it "is usable in a ruby manner and yields itself when opened" do
         | 
| 57 75 | 
             
                HTAuth::PasswdFile.open(@tf.path) do |pf|
         | 
| 58 76 | 
             
                  pf.add_or_update("alice", "a new secret", "md5")
         | 
| 59 77 | 
             
                  pf.delete('bob')
         | 
| 60 78 | 
             
                end
         | 
| 61 79 | 
             
                lines = IO.readlines(@tf.path)
         | 
| 62 | 
            -
                lines.size.must_equal 1
         | 
| 63 | 
            -
                lines.first.split(':').first.must_equal "alice"
         | 
| 64 | 
            -
                lines.first.split(':').last.must_match( /\$apr1\$/ )
         | 
| 80 | 
            +
                _(lines.size).must_equal 1
         | 
| 81 | 
            +
                _(lines.first.split(':').first).must_equal "alice"
         | 
| 82 | 
            +
                _(lines.first.split(':').last).must_match( /\$apr1\$/ )
         | 
| 65 83 | 
             
              end
         | 
| 66 84 | 
             
            end
         | 
    
        data/spec/plaintext_spec.rb
    CHANGED
    
    | @@ -2,14 +2,10 @@ require 'spec_helper' | |
| 2 2 | 
             
            require 'htauth/plaintext'
         | 
| 3 3 |  | 
| 4 4 | 
             
            describe HTAuth::Plaintext do
         | 
| 5 | 
            -
              it "has a prefix" do
         | 
| 6 | 
            -
                HTAuth::Plaintext.new.prefix.must_equal ""
         | 
| 7 | 
            -
              end
         | 
| 8 | 
            -
             | 
| 9 5 | 
             
              it "encrypts the same way that apache does" do
         | 
| 10 6 | 
             
                apache_result = "a secret"
         | 
| 11 7 | 
             
                pt = HTAuth::Plaintext.new
         | 
| 12 | 
            -
                pt.encode("a secret").must_equal apache_result
         | 
| 8 | 
            +
                _(pt.encode("a secret")).must_equal apache_result
         | 
| 13 9 | 
             
              end
         | 
| 14 10 | 
             
            end
         | 
| 15 11 |  | 
    
        data/spec/sha1_spec.rb
    CHANGED
    
    | @@ -2,14 +2,10 @@ require 'spec_helper' | |
| 2 2 | 
             
            require 'htauth/sha1'
         | 
| 3 3 |  | 
| 4 4 | 
             
            describe HTAuth::Sha1 do
         | 
| 5 | 
            -
              it "has a prefix" do
         | 
| 6 | 
            -
                HTAuth::Sha1.new.prefix.must_equal "{SHA}"
         | 
| 7 | 
            -
              end
         | 
| 8 | 
            -
             | 
| 9 5 | 
             
              it "encrypts the same way that apache does" do
         | 
| 10 6 | 
             
                apache_result = "{SHA}ZrnlrvmM7ZCOV3FAvM7la89NKbk="
         | 
| 11 7 | 
             
                sha1 = HTAuth::Sha1.new
         | 
| 12 | 
            -
                sha1.encode("a secret").must_equal apache_result
         | 
| 8 | 
            +
                _(sha1.encode("a secret")).must_equal apache_result
         | 
| 13 9 | 
             
              end
         | 
| 14 10 | 
             
            end
         | 
| 15 11 |  | 
    
        data/tasks/default.rake
    CHANGED
    
    | @@ -38,7 +38,7 @@ task :develop => "develop:default" | |
| 38 38 | 
             
            begin
         | 
| 39 39 | 
             
              require 'rake/testtask'
         | 
| 40 40 | 
             
              Rake::TestTask.new( :test ) do |t|
         | 
| 41 | 
            -
                t.ruby_opts    = %w[ -w  | 
| 41 | 
            +
                t.ruby_opts    = %w[ -w ]
         | 
| 42 42 | 
             
                t.libs         = %w[ lib spec test ]
         | 
| 43 43 | 
             
                t.pattern      = "{test,spec}/**/{test_*,*_spec}.rb"
         | 
| 44 44 | 
             
              end
         | 
| @@ -159,7 +159,7 @@ namespace :fixme do | |
| 159 159 | 
             
              end
         | 
| 160 160 |  | 
| 161 161 | 
             
              desc "See if the fixme tools are outdated"
         | 
| 162 | 
            -
              task :outdated  | 
| 162 | 
            +
              task :outdated do
         | 
| 163 163 | 
             
                if fixme_up_to_date? then
         | 
| 164 164 | 
             
                  puts "Fixme files are up to date."
         | 
| 165 165 | 
             
                else
         | 
| @@ -170,7 +170,7 @@ namespace :fixme do | |
| 170 170 | 
             
              end
         | 
| 171 171 |  | 
| 172 172 | 
             
              desc "Update outdated fixme files"
         | 
| 173 | 
            -
              task :update  | 
| 173 | 
            +
              task :update do
         | 
| 174 174 | 
             
                if fixme_up_to_date? then
         | 
| 175 175 | 
             
                  puts "Fixme files are already up to date."
         | 
| 176 176 | 
             
                else
         | 
    
        data/tasks/this.rb
    CHANGED
    
    | @@ -28,7 +28,7 @@ class ThisProject | |
| 28 28 | 
             
                @exclude_from_manifest = Regexp.union(/\.(git|DS_Store)/,
         | 
| 29 29 | 
             
                                                      /^(doc|coverage|pkg|tmp|Gemfile(\.lock)?)/,
         | 
| 30 30 | 
             
                                                      /^[^\/]+\.gemspec/,
         | 
| 31 | 
            -
                                                      /\.(swp|jar|bundle|so|rvmrc|travis.yml)$/,
         | 
| 31 | 
            +
                                                      /\.(swp|jar|bundle|so|rvmrc|travis.yml|byebug_history|fossa.yml|ruby-version)$/,
         | 
| 32 32 | 
             
                                                      /~$/)
         | 
| 33 33 | 
             
                @gemspecs              = Hash.new
         | 
| 34 34 | 
             
                yield self if block_given?
         | 
| @@ -146,7 +146,7 @@ class ThisProject | |
| 146 146 | 
             
                  spec.rdoc_options = [ "--main"  , 'README.md',
         | 
| 147 147 | 
             
                                        "--markup", "tomdoc" ]
         | 
| 148 148 |  | 
| 149 | 
            -
                  spec.required_ruby_version = '>=  | 
| 149 | 
            +
                  spec.required_ruby_version = '>= 2.2.2'
         | 
| 150 150 | 
             
                end
         | 
| 151 151 | 
             
              end
         | 
| 152 152 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,71 +1,85 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: htauth
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Jeremy Hinegardner
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2020-04-02 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bcrypt
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '3.1'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '3.1'
         | 
| 13 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 28 | 
             
              name: rake
         | 
| 15 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 30 | 
             
                requirements:
         | 
| 17 31 | 
             
                - - "~>"
         | 
| 18 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: ' | 
| 33 | 
            +
                    version: '13.0'
         | 
| 20 34 | 
             
              type: :development
         | 
| 21 35 | 
             
              prerelease: false
         | 
| 22 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 37 | 
             
                requirements:
         | 
| 24 38 | 
             
                - - "~>"
         | 
| 25 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: ' | 
| 40 | 
            +
                    version: '13.0'
         | 
| 27 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 42 | 
             
              name: minitest
         | 
| 29 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 44 | 
             
                requirements:
         | 
| 31 45 | 
             
                - - "~>"
         | 
| 32 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: '5. | 
| 47 | 
            +
                    version: '5.5'
         | 
| 34 48 | 
             
              type: :development
         | 
| 35 49 | 
             
              prerelease: false
         | 
| 36 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 51 | 
             
                requirements:
         | 
| 38 52 | 
             
                - - "~>"
         | 
| 39 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version: '5. | 
| 54 | 
            +
                    version: '5.5'
         | 
| 41 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 56 | 
             
              name: rdoc
         | 
| 43 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 58 | 
             
                requirements:
         | 
| 45 59 | 
             
                - - "~>"
         | 
| 46 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            -
                    version: ' | 
| 61 | 
            +
                    version: '6.2'
         | 
| 48 62 | 
             
              type: :development
         | 
| 49 63 | 
             
              prerelease: false
         | 
| 50 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 65 | 
             
                requirements:
         | 
| 52 66 | 
             
                - - "~>"
         | 
| 53 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            -
                    version: ' | 
| 68 | 
            +
                    version: '6.2'
         | 
| 55 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 70 | 
             
              name: simplecov
         | 
| 57 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 72 | 
             
                requirements:
         | 
| 59 73 | 
             
                - - "~>"
         | 
| 60 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: '0. | 
| 75 | 
            +
                    version: '0.17'
         | 
| 62 76 | 
             
              type: :development
         | 
| 63 77 | 
             
              prerelease: false
         | 
| 64 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 79 | 
             
                requirements:
         | 
| 66 80 | 
             
                - - "~>"
         | 
| 67 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: '0. | 
| 82 | 
            +
                    version: '0.17'
         | 
| 69 83 | 
             
            description: HTAuth is a pure ruby replacement for the Apache support programs htdigest
         | 
| 70 84 | 
             
              and htpasswd.  Command line and API access are provided for access to htdigest and
         | 
| 71 85 | 
             
              htpasswd files.
         | 
| @@ -90,11 +104,13 @@ files: | |
| 90 104 | 
             
            - bin/htpasswd-ruby
         | 
| 91 105 | 
             
            - lib/htauth.rb
         | 
| 92 106 | 
             
            - lib/htauth/algorithm.rb
         | 
| 107 | 
            +
            - lib/htauth/bcrypt.rb
         | 
| 93 108 | 
             
            - lib/htauth/cli.rb
         | 
| 94 109 | 
             
            - lib/htauth/cli/digest.rb
         | 
| 95 110 | 
             
            - lib/htauth/cli/passwd.rb
         | 
| 96 111 | 
             
            - lib/htauth/console.rb
         | 
| 97 112 | 
             
            - lib/htauth/crypt.rb
         | 
| 113 | 
            +
            - lib/htauth/descendant_tracker.rb
         | 
| 98 114 | 
             
            - lib/htauth/digest_entry.rb
         | 
| 99 115 | 
             
            - lib/htauth/digest_file.rb
         | 
| 100 116 | 
             
            - lib/htauth/entry.rb
         | 
| @@ -106,6 +122,8 @@ files: | |
| 106 122 | 
             
            - lib/htauth/plaintext.rb
         | 
| 107 123 | 
             
            - lib/htauth/sha1.rb
         | 
| 108 124 | 
             
            - lib/htauth/version.rb
         | 
| 125 | 
            +
            - spec/algorithm_spec.rb
         | 
| 126 | 
            +
            - spec/bcrypt_spec.rb
         | 
| 109 127 | 
             
            - spec/cli/digest_spec.rb
         | 
| 110 128 | 
             
            - spec/cli/passwd_spec.rb
         | 
| 111 129 | 
             
            - spec/crypt_spec.rb
         | 
| @@ -143,21 +161,22 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 143 161 | 
             
              requirements:
         | 
| 144 162 | 
             
              - - ">="
         | 
| 145 163 | 
             
                - !ruby/object:Gem::Version
         | 
| 146 | 
            -
                  version:  | 
| 164 | 
            +
                  version: 2.2.2
         | 
| 147 165 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 148 166 | 
             
              requirements:
         | 
| 149 167 | 
             
              - - ">="
         | 
| 150 168 | 
             
                - !ruby/object:Gem::Version
         | 
| 151 169 | 
             
                  version: '0'
         | 
| 152 170 | 
             
            requirements: []
         | 
| 153 | 
            -
             | 
| 154 | 
            -
            rubygems_version: 2.4.5
         | 
| 171 | 
            +
            rubygems_version: 3.0.3
         | 
| 155 172 | 
             
            signing_key: 
         | 
| 156 173 | 
             
            specification_version: 4
         | 
| 157 174 | 
             
            summary: HTAuth is a pure ruby replacement for the Apache support programs htdigest
         | 
| 158 175 | 
             
              and htpasswd.  Command line and API access are provided for access to htdigest and
         | 
| 159 176 | 
             
              htpasswd files.
         | 
| 160 177 | 
             
            test_files:
         | 
| 178 | 
            +
            - spec/algorithm_spec.rb
         | 
| 179 | 
            +
            - spec/bcrypt_spec.rb
         | 
| 161 180 | 
             
            - spec/cli/digest_spec.rb
         | 
| 162 181 | 
             
            - spec/cli/passwd_spec.rb
         | 
| 163 182 | 
             
            - spec/crypt_spec.rb
         |