ওয়েব অ্যাপ্লিকেশনগুলির একটি সাধারণ প্রয়োজন হল নির্দিষ্ট ভূমিকা এবং অনুমতি প্রদান করার ক্ষমতা৷
অনেক ধরনের ওয়েব অ্যাপ্লিকেশন সীমিত অ্যাক্সেস প্রদানের ক্ষেত্রে অ্যাডমিন এবং নিয়মিত ব্যবহারকারীদের মধ্যে পার্থক্য করে। এটি প্রায়শই একটি সাধারণ বুলিয়ান ব্যবহার করে সঞ্চালিত হয় যা নির্ধারণ করে যে ব্যবহারকারী একজন প্রশাসক কিনা। যাইহোক, ভূমিকা এবং অনুমতি অনেক বেশি জটিল হয়ে উঠতে পারে।
আপনার অ্যাপ্লিকেশনের মূল্য নির্দিষ্ট ডেটা এবং ক্রিয়াগুলিতে অ্যাক্সেস সীমাবদ্ধ করার মধ্যে রয়েছে। এটি অবশ্যই এমন কিছু যা আপনি বিশৃঙ্খলা করতে চান না। এই পোস্টে, আমরা ব্যাখ্যা করব কীভাবে একটি বেসিক রুবি অন রেল অ্যাপ্লিকেশনে ভূমিকা এবং অনুমতি প্রয়োগ করতে হয়৷
অনুমতি পরিচালনা করার জন্য আমার কি একটি রত্ন দরকার?
না, আপনার কোনো রত্ন প্রয়োজন নেই, বিশেষ করে যদি আপনার আবেদন ছোট হয় এবং আপনি আপনার কোড বেসে আরও নির্ভরতা যোগ করা এড়াতে চান। তবে, আপনি যদি বিকল্প খুঁজছেন, এখানে সবচেয়ে জনপ্রিয় রত্ন রয়েছে যা ভূমিকা এবং অনুমতি নিয়ে কাজ করে :
-
DeviseDevise হল প্রমাণীকরণ এবং ভূমিকা পরিচালনার জন্য একটি রত্ন, এবং এটি সত্যিই একটি জটিল এবং শক্তিশালী সমাধান৷ GitHub-এ 21.7k স্টার সহ, এটি এই পোস্টে সবচেয়ে জনপ্রিয় রেপো, তবে এটি ভূমিকা পরিচালনার চেয়েও বেশি কিছু করে৷ এটি একটি প্রমাণীকরণ সমাধান হিসাবে পরিচিত, তাই শুধুমাত্র আপনার কোডবেসে এটি প্রয়োগ করুন যদি আপনার একটি খুব শক্তিশালী লাইব্রেরির প্রয়োজন হয়৷
-
পন্ডিত:পন্ডিত হল একটি রত্ন যা সাধারণ রুবি বস্তু ব্যবহার করে এবং এটি সম্ভবত সবচেয়ে সহজ পলিসি রত্ন যা আমরা কভার করব। ব্যবহার করা সহজ, ন্যূনতম অনুমোদন আছে এবং বিশুদ্ধ রুবি ব্যবহারের অনুরূপ। GitHub-এ 7.3k তারা সহ, এটি বর্তমানে সবচেয়ে জনপ্রিয় নীতি রত্ন৷
৷ -
CanCan:CanCan হল একটি অনুমোদন লাইব্রেরি যা প্রদত্ত ব্যবহারকারীকে অ্যাক্সেস করার অনুমতি দেওয়া সংস্থানগুলিকে সীমাবদ্ধ করে। যাইহোক, CanCan বছরের পর বছর ধরে পরিত্যক্ত হয়েছে এবং শুধুমাত্র Rails 3 এবং তার আগের রিলিজের সাথে কাজ করে।
-
CanCanCan:CanCanCan হল রুবি এবং রুবি অন রেলের জন্য আরেকটি অনুমোদনের লাইব্রেরি। এটি CanCan এর বিকল্প এবং বর্তমানে রক্ষণাবেক্ষণ করা হচ্ছে। GitHub-এ 4.9k তারকা সহ, এটি সর্বনিম্ন জনপ্রিয়, তবে এটি বেশ ভাল কাজ করে এবং ভালভাবে রক্ষণাবেক্ষণ করা হয়।
এই সমস্ত রত্নগুলি দুর্দান্ত, তবে সাধারণ রুবিতে নিজের অনুমতিগুলি তৈরি করা খুব কঠিন নয়। পলিসি অবজেক্ট প্যাটার্ন নামে একটি কৌশল ব্যবহার করে আমি আপনাকে দেখাব কিভাবে রত্ন ছাড়াই অনুমতিগুলি পরিচালনা করতে হয়।
নীতি অবজেক্ট প্যাটার্ন
পলিসি অবজেক্ট হল একটি ডিজাইন প্যাটার্ন যা অনুমতি এবং ভূমিকা মোকাবেলা করতে ব্যবহৃত হয়। আপনি প্রতিবার এটি ব্যবহার করতে পারেন যখন আপনাকে কিছু বা কাউকে একটি ক্রিয়া সম্পাদন করার অনুমতি দেওয়া হয়েছে কিনা তা পরীক্ষা করতে হবে। এটি জটিল ব্যবসায়িক নিয়মগুলিকে অন্তর্ভুক্ত করে এবং সহজেই বিভিন্ন নিয়মের সাথে অন্যান্য নীতি বস্তু দ্বারা প্রতিস্থাপিত হতে পারে। সমস্ত বাহ্যিক নির্ভরতা নীতি অবজেক্টে ইনজেকশন করা হয়, অনুমতি চেক লজিককে এনক্যাপসুলেট করে, যার ফলে একটি পরিষ্কার নিয়ামক এবং মডেল হয়। পন্ডিত, ক্যানকান এবং ক্যানকানকানের মতো রত্ন এই প্যাটার্নটি বাস্তবায়ন করে।
বিশুদ্ধ নীতি বস্তুর নিয়ম
- রিটার্ন একটি বুলিয়ান মান হতে হবে
- যুক্তি সহজ হতে হবে
- পদ্ধতির ভিতরে, আমাদের শুধুমাত্র পাস করা বস্তুতে মেথড কল করা উচিত
বাস্তবায়ন
নামকরণের রীতি দিয়ে শুরু করা যাক; ফাইলের নামের _policy
আছে প্রত্যয় প্রয়োগ করা হয় এবং শেষে ক্লাস এবং নীতি। এই পদ্ধতিতে, নাম সবসময় ?
দিয়ে শেষ হয়। অক্ষর (যেমন,UsersPolicy#allowed?
)।
এখানে কিছু উদাহরণ কোড আছে:
class UsersPolicy
def initialize(user)
@user = user
end
def allowed?
admin? || editor?
end
def editor?
@user.where(editor: true)
end
def admin?
@user.where(admin: true)
end
end
কোন পরিস্থিতিতে আমি এগুলি ব্যবহার করব?
যখন আপনার অ্যাপে একাধিক ধরনের সীমাবদ্ধ অ্যাক্সেস এবং সীমাবদ্ধ অ্যাকশন থাকে। উদাহরণস্বরূপ, নিম্নলিখিতগুলি দিয়ে পোস্ট তৈরি করা যেতে পারে:
- অন্তত একটি ট্যাগ,
- একটি সীমাবদ্ধতা যা শুধুমাত্র প্রশাসক এবং সম্পাদকরাই তৈরি করতে পারে এবং
- একটি প্রয়োজনীয়তা যা সম্পাদকদের যাচাই করা দরকার।
নীতি অবজেক্ট ছাড়া এখানে একটি উদাহরণ নিয়ামক:
class PostsController < ApplicationController
def create
if @post.tag_ids.size > 0
&& (current_user.role == ‘admin’
|| (current_user.role == ‘editor’ && current_user.verified_email))
# create
end
end
end
যেহেতু উপরের কন্ডিশন চেকগুলি দীর্ঘ, কুৎসিত এবং অপঠিত, তাই নীতি অবজেক্ট প্যাটার্ন প্রয়োগ করা উচিত৷
চলুন শুরু করা যাক PostsCreationPolicy
তৈরি করে .
class PostsCreationPolicy
attr_reader :user, :post
def initialize(user, post)
@user = user
@post = post
end
def self.create?(user, post)
new(user, post).create?
end
def create?
with_tags? && author_is_allowed?
end
private
def with_tags?
post.tag_ids.size > 0
end
def author_is_allowed?
is_admin? || editor_is_verified?
end
def is_admin?
user.role == ‘admin’
end
def editor_is_verified?
user.role == ‘editor` && user.verified_email
end
end
পলিসি অবজেক্টের সাথে আমাদের কন্ট্রোলার এইরকম দেখায়:
class PostsController < ApplicationController
def create
if PostsCreationPolicy.create?(current_user, @post)
# create
end
end
end
কিভাবে রেলে নীতি অবজেক্ট ব্যবহার করবেন
অ্যাপ /policies
-এর ভিতরে একটি নীতি নির্দেশিকা তৈরি করুন এবং সেখানে আপনার সমস্ত পলিসি ক্লাস রাখুন। যখন আপনাকে কন্ট্রোলারকে কল করতে হবে, তখন আপনি সরাসরি একটি অ্যাকশনে তা করতে পারেন বা একটি before_action
ব্যবহার করতে পারেন :
class PostsController < ApplicationController
before_action :authorized?, only: [:edit, :create, :update, :destroy]
def authorized?
unless ::PostsCreationPolicy.create?(current_user, @post)
render :file => "public/404.html", :status => :unauthorized
end
end
end
পলিসির বিষয়গুলো কিভাবে পরীক্ষা করা যায়
কন্ট্রোলারে আচরণ পরীক্ষা করা সহজ:
require 'rails_helper'
RSpec.describe "/posts", type: :request do
describe "when user is not allowed" do
let(:user_not_allowed) { create(:user, admin: false, editor: false) }
let(:tag) { create(:tag) }
let(:valid_attributes) { attributes_for(:post, tag_id: tag.id) }
before do
sign_in user_not_allowed
end
describe "GET /index" do
it "return code 401" do
diet = Post.create! valid_attributes
get edit_post_url(post)
expect(response).to have_http_status(401)
end
end
end
end
নীতি পরীক্ষা করাও সহজ; শুধুমাত্র একটি দায়িত্ব সহ আমাদের অনেকগুলি ছোট পদ্ধতি রয়েছে৷
require 'rails_helper'
RSpec.describe PostsCreationPolicy do
describe "when user is not allowed" do
let(:user) { create(:user, editor: false, admin: false) }
let(:user_editor) { create(:user, editor: true, email: verified) }
let(:tag) { create(:tag) }
let(:post) { create(:post, tag_id: tag.id) }
describe ".create?" do
context "when user is allowed" do
it "creates a new post" do
expect(described_class.create?(user_editor, post)).to eq(true)
end
end
context "when user is not allowed" do
it "does not create a new post" do
expected(described_class.create?(user, post)).to eq(false)
end
end
end
# ...more test cases
end
end
আমরা পরীক্ষা করি যে বস্তুটিকে প্রতিটি পরিস্থিতিতে তৈরি করার অনুমতি দেওয়া হয় কিনা৷
উপসংহার
পলিসি প্যাটার্ন ধারণাটি ছোট কিন্তু বড় ফলাফল দেয়। প্রতিবার যখন আপনাকে সহজ বা জটিল অনুমতির মোকাবিলা করতে হয় তখন একটি পলিসি অবজেক্ট প্রয়োগ করার কথা বিবেচনা করুন। যখন RSpec এর সাথে পরীক্ষার কথা আসে, তখন আপনাকে ডাটাবেস রেকর্ড ব্যবহার করতে হবে না; আপনার নীতিগুলি সম্পূর্ণরূপে রুবি বস্তু, এবং আপনার পরীক্ষা সহজ এবং দ্রুত হবে৷
৷