DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

User Management Module In Ruby

08.21.2008
| 3256 views |
  • submit to reddit
        
#!/usr/bin/ruby -Ku

# user management system

###############################################################################
=begin

- 新規ユーザ登録
- ログイン認証

ができます。

想定するテーブル構成:
	CREATE TABLE `user_table` (
		`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
		`name` VARCHAR(32) NOT NULL,
		`cryptedPassword` VARCHAR(40) NOT NULL,
		`salt` VARCHAR(8) NOT NULL,
		`email` VARCHAR(32),
		`createdAt` DATETIME,
		PRIMARY KEY (`id`, `name`),
		UNIQUE(`name`)
	);

- salt
- 暗号化はSHA1で行うので、長さは40文字

発生する例外:
	新規ユーザ登録時:
		"UserAlreadyExist"
	ログイン認証時:
		"UserNotExist"
		"PasswordNotMatch"

=end
###############################################################################

module UserMan
	UserTableName = "user_table"


	# 新規ユーザの追加
	def add_new_user(db, name, pass, email, salt_len=8)
		user_id = get_user_id(db, name)
		if user_id
			raise "UserAlreadyExist"
			return false
		end

		salt = create_salt(salt_len)
		enc_pass = encrypt_password(pass, salt)
		createdAt = Time.now.strftime("%Y-%m-%d %H:%M:%S")

		fields = ["name", "cryptedPassword", "salt", "email", "createdAt"]
		r = db.insert(UserTableName, fields, name, enc_pass, salt, email, createdAt)

		return true
	end


	# ユーザid の取得
	def get_user_id(db, name)
		db.query1("select id from #{UserTableName} where name=? limit 1;", name)
	end


	# salt 生成
	def create_salt(salt_len, chrs='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()-=+*;:{}[]~|')
		n = chrs.length
		(0...salt_len).map do
			chrs[rand(n), 1]
		end.join
	end


	# パスワードの暗号化
	def encrypt_password(pass, salt)
		require "digest/sha1"
		Digest::SHA1.hexdigest("#{pass}:#{salt}")
	end


	# ログイン認証
	#	認証に成功したら、id を返す
	def login_authorize_get_id(db, name, pass)
		r = db.query1("select id, salt, cryptedPassword from #{UserTableName} where name=? limit 1;", name)
		unless r
			raise "UserNotExist"
			return false
		end

		enc_pass = encrypt_password(pass, r["salt"])
		if enc_pass != r["cryptedPassword"]
			raise "PasswordNotMatch"
			return false
		end

		return r["id"].to_i
	end
end



if $0 == __FILE__
	include UserMan
	require 'setting'

	def with_open_mydb(&block)
		require "db"
		db = MySQLDatabase.new
		db.connect(DBHost, DBUser, DBPass, DBName)
		block.call(db)
	ensure
		db.close
	end

	r = with_open_mydb do |db|
#		create_salt(8)
#		add_new_user(db, "anonymous", "mypassword", "hoge@example.com")
#		(with_open_mydb {|db| get_user_id(db, "anonymous")})
		login_authorize_get_id(db, "anonymous", "mypassword")
	end
	p r
end