Sunday, July 19, 2009

Apache: Enable access to the file in the directory protected with .htaccess

To protect our QA Apache web server from spammers with basic authentication, we use following .htaccess access file in the root directory of the web server:
AuthUserFile /secure-folder/.htpasswd
AuthGroupFile /dev/null
AuthName "Password Protected Area"
AuthType Basic
<limit GET POST>
require valid-user
</limit>

Now if you want to provide access to the file(s) in the sub directory below you should create separate .htaccess file for that sub directory and use Satisfy directive

<FilesMatch "^you-file-name$">
allow from all
Satisfy Any
</FilesMatch>

Sunday, March 15, 2009

Convert 15-character Salesforce IDs to 18-characters IDs with Ruby



Algorithm:

Saleforce uses 15-character IDs as primary keys for every record.
When retrieving an ID over the API, 18-character case-insensitive IDs are returned.
Generally, this doesn't cause any problems because the 18-character version can be used anywhere the 15-character one is.
One problem arises though when you are storing IDs in a text field.
In this case, you may need to convert a 15-character ID into its 18-character version.

All case-sensitive ids are 15 chars.
To convert a 15 char case-sensitive id to an 18 char case-safe id follow these steps.
1. Divide the 15 char into 3 chunks of 5 chars each.
2. For each character give that position a value of 1 if uppercase, 0 otherwise (lowercase or number).
3. Combine the bits from each chunk into a 5 bit integer where the rightmost bit is the most significant bit. This will yield a number between 0 and 31 for each chunk.
4. Constuct an array that contains the sequence of capital letters A-Z and 0-5.
5. Use the integer from each chunk to choose a character from the array.
6. Append the resulting 3 characters, in chunk order, to the end of the 15 char id.


I used this code as example.


  1. def sf15to18(sf_id15)

  2. map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'

  3. extra = ''

  4. sf_id15.scan(/.{5}/).each do |chunk|

  5. bits = []

  6. chunk.scan(/.{1}/).each do |char|

  7. #Uppercase condition

  8. bits.unshift( (char.to_i == 0 && char != 0 && char.downcase != char) ? 1 : 0)

  9. end


  10. ind = bits.inject(0) do |ind, bit|

  11. ind + ind + bit

  12. end

  13. extra += map[ind..ind]

  14. end

  15. sf_id15 + extra

  16. end