angular_rails_csrf 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d7d66db0ae4313bd633c3eca8e80a4ca04180930
4
+ data.tar.gz: 56a71c51c6d1f9231f7d5e38639e5f278103bd6a
5
+ SHA512:
6
+ metadata.gz: e4db30cd919b7fe492a363540fa7f40d6f5ac07dfaa17e2ebd9f499651dff5425de3ab2208a8da13941b6a8a7646fe6dcbb83b63aa036ff00968b8b96b19a50a
7
+ data.tar.gz: b1cf4a627b2c215d97ca7b8b4fdcc6a09e18b1020d236f0c540bde4d27468894f58cf9ede7addf85985dfd8520ae434c7a8e87f320676236a23c6fe7597afb6e
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ ## AngularJS-style CSRF Protection for Rails
2
+
3
+ The AngularJS [ng.$http](http://docs.angularjs.org/api/ng.$http) service has built-in CSRF protection. By default, it looks for a cookie named `XSRF-TOKEN` and, if found, writes its value into an `X-XSRF-TOKEN` header, which the server compares with the CSRF token saved in the user's session.
4
+
5
+ This project adds direct support for this scheme to your Rails application without requiring any changes to your AngularJS application. It also doesn't require the use of `csrf_meta_tags` to write a CSRF token into your page markup, so it works for pure JSON API applications.
6
+
7
+ Note that there is nothing AngularJS specific here, and this will work with any other front-end that implements the same scheme.
8
+
9
+ ### Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'angular_rails_csrf'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ That's it!
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'AngularRailsCsrf'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1 @@
1
+ require 'angular_rails_csrf/railtie'
@@ -0,0 +1,17 @@
1
+ module AngularRailsCsrf
2
+ module Concern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ after_action :set_xsrf_token_cookie
7
+ end
8
+
9
+ def set_xsrf_token_cookie
10
+ cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
11
+ end
12
+
13
+ def verified_request?
14
+ super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ require 'angular_rails_csrf/concern'
2
+
3
+ module AngularRailsCsrf
4
+ class Railtie < ::Rails::Railtie
5
+ initializer 'angular-rails-csrf' do |app|
6
+ ActiveSupport.on_load(:action_controller) do
7
+ include AngularRailsCsrf::Concern
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module AngularRailsCsrf
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class AngularRailsCsrfTest < ActionController::TestCase
4
+ tests ApplicationController
5
+
6
+ setup do
7
+ @controller.allow_forgery_protection = true
8
+ @correct_token = @controller.send(:form_authenticity_token)
9
+ end
10
+
11
+ test "a get sets the XSRF-TOKEN cookie but does not require the X-XSRF-TOKEN header" do
12
+ get :index
13
+ assert_equal @correct_token, cookies['XSRF-TOKEN']
14
+ assert_response :success
15
+ end
16
+
17
+ test "a post raises an error without the X-XSRF-TOKEN header set" do
18
+ assert_raises ActionController::InvalidAuthenticityToken do
19
+ post :create
20
+ end
21
+ end
22
+
23
+ test "a post raises an error with the X-XSRF-TOKEN header set to the wrong value" do
24
+ @request.headers['X-XSRF-TOKEN'] = 'garbage'
25
+ assert_raises ActionController::InvalidAuthenticityToken do
26
+ post :create
27
+ end
28
+ end
29
+
30
+ test "a post is accepted if X-XSRF-TOKEN is set properly" do
31
+ @request.headers['X-XSRF-TOKEN'] = @correct_token
32
+ post :create
33
+ assert_response :success
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery with: :exception
3
+
4
+ def index; head :ok; end
5
+ def create; head :ok; end
6
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require "action_controller/railtie"
4
+
5
+ Bundler.require(*Rails.groups)
6
+ require "angular_rails_csrf"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ config.secret_key_base = '5e6b6d2bd7bf26d02679ac958b520adf41b211eb0b8f33742abc5437711d0ad314baf13efc0d35d7568d2e469668a7021cf5e945c667bd16507777aedb770f83'
11
+ config.eager_load = false # You get yelled at if you don't set this
12
+ end
13
+ end
14
+
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the Rails application.
5
+ Dummy::Application.initialize!
@@ -0,0 +1,4 @@
1
+ Dummy::Application.routes.draw do
2
+ get 'test' => 'application#index'
3
+ post 'test' => 'application#create'
4
+ end
@@ -0,0 +1,176 @@
1
+ --------------------------------------------------------------------------------------------------------
2
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
3
+ --------------------------------------------------------------------------------------------------------
4
+ Processing by ApplicationController#index as HTML
5
+ Completed 200 OK in 0ms
6
+ -----------------------------------------------------------------------------
7
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
8
+ -----------------------------------------------------------------------------
9
+ Processing by ApplicationController#create as HTML
10
+ Completed 200 OK in 0ms
11
+ -----------------------------------------------------------------------------------------------------
12
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
13
+ -----------------------------------------------------------------------------------------------------
14
+ Processing by ApplicationController#create as HTML
15
+ Can't verify CSRF token authenticity
16
+ Completed 422 Unprocessable Entity in 0ms
17
+ -------------------------------------------------------------------------------------
18
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
19
+ -------------------------------------------------------------------------------------
20
+ Processing by ApplicationController#create as HTML
21
+ Can't verify CSRF token authenticity
22
+ Completed 422 Unprocessable Entity in 0ms
23
+ --------------------------------------------------------------------------------------------------------
24
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
25
+ --------------------------------------------------------------------------------------------------------
26
+ Processing by ApplicationController#index as HTML
27
+ Completed 200 OK in 0ms
28
+ -----------------------------------------------------------------------------
29
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
30
+ -----------------------------------------------------------------------------
31
+ Processing by ApplicationController#create as HTML
32
+ Completed 200 OK in 0ms
33
+ -----------------------------------------------------------------------------------------------------
34
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
35
+ -----------------------------------------------------------------------------------------------------
36
+ Processing by ApplicationController#create as HTML
37
+ Can't verify CSRF token authenticity
38
+ Completed 422 Unprocessable Entity in 0ms
39
+ -------------------------------------------------------------------------------------
40
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
41
+ -------------------------------------------------------------------------------------
42
+ Processing by ApplicationController#create as HTML
43
+ Can't verify CSRF token authenticity
44
+ Completed 422 Unprocessable Entity in 0ms
45
+ --------------------------------------------------------------------------------------------------------
46
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
47
+ --------------------------------------------------------------------------------------------------------
48
+ Processing by ApplicationController#index as HTML
49
+ Completed 200 OK in 0ms
50
+ -----------------------------------------------------------------------------
51
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
52
+ -----------------------------------------------------------------------------
53
+ Processing by ApplicationController#create as HTML
54
+ Completed 200 OK in 0ms
55
+ -----------------------------------------------------------------------------------------------------
56
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
57
+ -----------------------------------------------------------------------------------------------------
58
+ Processing by ApplicationController#create as HTML
59
+ Can't verify CSRF token authenticity
60
+ Completed 422 Unprocessable Entity in 0ms
61
+ -------------------------------------------------------------------------------------
62
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
63
+ -------------------------------------------------------------------------------------
64
+ Processing by ApplicationController#create as HTML
65
+ Can't verify CSRF token authenticity
66
+ Completed 422 Unprocessable Entity in 0ms
67
+ --------------------------------------------------------------------------------------------------------
68
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
69
+ --------------------------------------------------------------------------------------------------------
70
+ Processing by ApplicationController#index as HTML
71
+ Completed 200 OK in 0ms
72
+ -----------------------------------------------------------------------------
73
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
74
+ -----------------------------------------------------------------------------
75
+ Processing by ApplicationController#create as HTML
76
+ Completed 200 OK in 0ms
77
+ -----------------------------------------------------------------------------------------------------
78
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
79
+ -----------------------------------------------------------------------------------------------------
80
+ Processing by ApplicationController#create as HTML
81
+ Can't verify CSRF token authenticity
82
+ Completed 422 Unprocessable Entity in 0ms
83
+ -------------------------------------------------------------------------------------
84
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
85
+ -------------------------------------------------------------------------------------
86
+ Processing by ApplicationController#create as HTML
87
+ Can't verify CSRF token authenticity
88
+ Completed 422 Unprocessable Entity in 0ms
89
+ --------------------------------------------------------------------------------------------------------
90
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
91
+ --------------------------------------------------------------------------------------------------------
92
+ Processing by ApplicationController#index as HTML
93
+ Completed 200 OK in 0ms
94
+ -----------------------------------------------------------------------------
95
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
96
+ -----------------------------------------------------------------------------
97
+ Processing by ApplicationController#create as HTML
98
+ Completed 200 OK in 0ms
99
+ -----------------------------------------------------------------------------------------------------
100
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
101
+ -----------------------------------------------------------------------------------------------------
102
+ Processing by ApplicationController#create as HTML
103
+ Can't verify CSRF token authenticity
104
+ Completed 422 Unprocessable Entity in 0ms
105
+ -------------------------------------------------------------------------------------
106
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
107
+ -------------------------------------------------------------------------------------
108
+ Processing by ApplicationController#create as HTML
109
+ Can't verify CSRF token authenticity
110
+ Completed 422 Unprocessable Entity in 0ms
111
+ --------------------------------------------------------------------------------------------------------
112
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
113
+ --------------------------------------------------------------------------------------------------------
114
+ Processing by ApplicationController#index as HTML
115
+ Completed 200 OK in 1ms
116
+ -----------------------------------------------------------------------------
117
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
118
+ -----------------------------------------------------------------------------
119
+ Processing by ApplicationController#create as HTML
120
+ Completed 200 OK in 0ms
121
+ -----------------------------------------------------------------------------------------------------
122
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
123
+ -----------------------------------------------------------------------------------------------------
124
+ Processing by ApplicationController#create as HTML
125
+ Can't verify CSRF token authenticity
126
+ Completed 422 Unprocessable Entity in 0ms
127
+ -------------------------------------------------------------------------------------
128
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
129
+ -------------------------------------------------------------------------------------
130
+ Processing by ApplicationController#create as HTML
131
+ Can't verify CSRF token authenticity
132
+ Completed 422 Unprocessable Entity in 0ms
133
+ --------------------------------------------------------------------------------------------------------
134
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
135
+ --------------------------------------------------------------------------------------------------------
136
+ Processing by ApplicationController#index as HTML
137
+ Completed 200 OK in 0ms
138
+ -----------------------------------------------------------------------------
139
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
140
+ -----------------------------------------------------------------------------
141
+ Processing by ApplicationController#create as HTML
142
+ Completed 200 OK in 0ms
143
+ -----------------------------------------------------------------------------------------------------
144
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
145
+ -----------------------------------------------------------------------------------------------------
146
+ Processing by ApplicationController#create as HTML
147
+ Can't verify CSRF token authenticity
148
+ Completed 422 Unprocessable Entity in 0ms
149
+ -------------------------------------------------------------------------------------
150
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
151
+ -------------------------------------------------------------------------------------
152
+ Processing by ApplicationController#create as HTML
153
+ Can't verify CSRF token authenticity
154
+ Completed 422 Unprocessable Entity in 0ms
155
+ --------------------------------------------------------------------------------------------------------
156
+ AngularRailsCsrfTest: test_a_get_sets_the_XSRF-TOKEN_cookie_but_does_not_require_the_X-XSRF-TOKEN_header
157
+ --------------------------------------------------------------------------------------------------------
158
+ Processing by ApplicationController#index as HTML
159
+ Completed 200 OK in 0ms
160
+ -----------------------------------------------------------------------------
161
+ AngularRailsCsrfTest: test_a_post_is_accepted_if_X-XSRF-TOKEN_is_set_properly
162
+ -----------------------------------------------------------------------------
163
+ Processing by ApplicationController#create as HTML
164
+ Completed 200 OK in 0ms
165
+ -----------------------------------------------------------------------------------------------------
166
+ AngularRailsCsrfTest: test_a_post_raises_an_error_with_the_X-XSRF-TOKEN_header_set_to_the_wrong_value
167
+ -----------------------------------------------------------------------------------------------------
168
+ Processing by ApplicationController#create as HTML
169
+ Can't verify CSRF token authenticity
170
+ Completed 422 Unprocessable Entity in 0ms
171
+ -------------------------------------------------------------------------------------
172
+ AngularRailsCsrfTest: test_a_post_raises_an_error_without_the_X-XSRF-TOKEN_header_set
173
+ -------------------------------------------------------------------------------------
174
+ Processing by ApplicationController#create as HTML
175
+ Can't verify CSRF token authenticity
176
+ Completed 422 Unprocessable Entity in 0ms
@@ -0,0 +1,5 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+ require "rails/test_help"
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: angular_rails_csrf
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Sanders
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 10.1.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 10.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '3'
34
+ - - <
35
+ - !ruby/object:Gem::Version
36
+ version: '5'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '3'
44
+ - - <
45
+ - !ruby/object:Gem::Version
46
+ version: '5'
47
+ description: AngularJS style CSRF protection for Rails
48
+ email:
49
+ - sanderjd@gmail.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/angular_rails_csrf/concern.rb
55
+ - lib/angular_rails_csrf/railtie.rb
56
+ - lib/angular_rails_csrf/version.rb
57
+ - lib/angular_rails_csrf.rb
58
+ - MIT-LICENSE
59
+ - Rakefile
60
+ - README.md
61
+ - test/angular_rails_csrf_test.rb
62
+ - test/dummy/app/controllers/application_controller.rb
63
+ - test/dummy/config/application.rb
64
+ - test/dummy/config/boot.rb
65
+ - test/dummy/config/environment.rb
66
+ - test/dummy/config/routes.rb
67
+ - test/dummy/config.ru
68
+ - test/dummy/log/test.log
69
+ - test/test_helper.rb
70
+ homepage: https://github.com/jsanders/angular_rails_csrf
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.1.10
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Support for AngularJS $http service style CSRF protection in Rails
94
+ test_files:
95
+ - test/angular_rails_csrf_test.rb
96
+ - test/dummy/app/controllers/application_controller.rb
97
+ - test/dummy/config/application.rb
98
+ - test/dummy/config/boot.rb
99
+ - test/dummy/config/environment.rb
100
+ - test/dummy/config/routes.rb
101
+ - test/dummy/config.ru
102
+ - test/dummy/log/test.log
103
+ - test/test_helper.rb