• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MushroomObserver / mushroom-observer / 14981230229

12 May 2025 07:49PM UTC coverage: 94.719% (+0.009%) from 94.71%
14981230229

Pull #2966

github

web-flow
Merge 5e859d14a into 20e3d01a4
Pull Request #2966: Fix comment broadcasting

15 of 15 new or added lines in 4 files covered. (100.0%)

7 existing lines in 5 files now uncovered.

34076 of 35976 relevant lines covered (94.72%)

484.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.7
/app/controllers/application_controller/authentication.rb
1
# frozen_string_literal: true
2

3
# see application_controller.rb
4
module ApplicationController::Authentication
1✔
5
  def self.included(base)
1✔
6
    base.helper_method(:check_permission, :reviewer?, :in_admin_mode?)
16,132✔
7
  end
8

9
  ##############################################################################
10
  #
11
  #  :section: User authentication
12
  #
13
  ##############################################################################
14

15
  # Filter that should run before everything else.  Establishes whether a User
16
  # is logged in or not.
17
  #
18
  # Stores the currently logged-in User in the "globals" <tt>@user</tt> and
19
  # <tt>User.current</tt>, as well as the session.  (The first is visible to
20
  # all controller instances and views; the second is visible to the entire
21
  # website application.)
22
  #
23
  # It first checks if the User is already logged in, i.e. is stored in the
24
  # session.  If not, it checks for an autologin cookie on the User's browser,
25
  # and logs them in automatically if so.
26
  #
27
  # In both cases, it makes sure the User actually exists and is verified.  If
28
  # not, the "user" is immediately logged out and the autologin cookie is
29
  # destroyed.
30
  #
31
  def autologin
1✔
32
    # render(plain: "Sorry, we've taken MO down to test something urgent."\
33
    #               "We'll be back in a few minutes. -Jason", layout: false)
34
    # return false
35

36
    # if browser.bot?
37
    #   render(status: 503, text: "robots are temporarily blocked from MO",
38
    #          layout: false)
39
    #   return false
40
    # end
41

42
    try_user_autologin(session_user)
3,387✔
43
    make_logged_in_user_available_to_everyone
3,387✔
44
    track_last_time_user_made_a_request
3,387✔
45
    block_suspended_users
3,387✔
46
    clear_admin_mode_for_nonadmins
3,387✔
47
  end
48

49
  private ##########
1✔
50

51
  def clear_user_globals
1✔
52
    @user = nil
3,548✔
53
    User.current = nil
3,548✔
54
  end
55

56
  # Save a lookup of the mrtg stats "user".
57
  MRTG_USER_ID = 164_054
1✔
58
  private_constant(:MRTG_USER_ID)
1✔
59

60
  def try_user_autologin(user_from_session)
1✔
61
    if Rails.env.production? && request.remote_ip == "127.0.0.1"
3,387✔
62
      # Request from the server itself, MRTG needs to log in to test page loads.
UNCOV
63
      login_valid_user(User.find(MRTG_USER_ID))
×
64
    elsif user_verified_and_allowed?(user_from_session)
3,387✔
65
      # User was already logged in.
66
      @user = user_from_session
2,656✔
67
    elsif user_verified_and_allowed?(user = validate_user_in_autologin_cookie)
731✔
68
      # User had "remember me" cookie set.
69
      login_valid_user(user)
3✔
70
    else
71
      delete_invalid_cookies
728✔
72
    end
73
  end
74

75
  def user_verified_and_allowed?(user)
1✔
76
    user&.verified && !user.blocked?
4,118✔
77
  end
78

79
  def validate_user_in_autologin_cookie
1✔
80
    return unless (cookie = cookies["mo_user"]) &&
731✔
81
                  (split = cookie.split) &&
4✔
82
                  (user = User.where(id: split[0]).first) &&
4✔
83
                  (split[1] == user.auth_code)
3✔
84

85
    user
3✔
86
  end
87

88
  def login_valid_user(user)
1✔
89
    @user = session_user_set(user)
3✔
90
    @user.last_login = Time.current
3✔
91
    @user.save
3✔
92

93
    # Reset cookie to push expiry forward.  This way it will continue to
94
    # remember the user until they are inactive for over a month.  (Else
95
    # they'd have to login every month, no matter how often they login.)
96
    autologin_cookie_set(user)
3✔
97
  end
98

99
  def delete_invalid_cookies
1✔
100
    clear_autologin_cookie
728✔
101
    session_user_set(nil)
728✔
102
  end
103

104
  def make_logged_in_user_available_to_everyone
1✔
105
    User.current = @user
3,387✔
106
    logger.warn("user=#{@user ? @user.id : "0"} " \
3,387✔
107
                "robot=#{browser.bot? ? "Y" : "N"} " \
108
                "ip=#{request.remote_ip}")
109
  end
110

111
  # Track when user last requested a page, but update at most once an hour.
112
  def track_last_time_user_made_a_request
1✔
113
    last_activity = @user&.last_activity&.to_fs("%Y%m%d%H")
3,387✔
114
    now = Time.current.to_fs("%Y%m%d%H")
3,387✔
115
    return if !@user || last_activity && last_activity >= now
3,387✔
116

117
    @user.last_activity = Time.current
1,536✔
118
    @user.save
1,536✔
119
  end
120

121
  def block_suspended_users
1✔
122
    return true unless @user&.blocked # Tell Rails to continue processing.
3,387✔
123

124
    render(plain: "Your account has been deleted.", layout: false)
×
UNCOV
125
    false # Tell Rails to stop processing.
×
126
  end
127

128
  def clear_admin_mode_for_nonadmins
1✔
129
    session[:admin] = false if session[:admin] && !@user&.admin
3,387✔
130
  end
131

132
  public ##########
1✔
133

134
  # ----------------------------
135
  #  "Public" methods.
136
  # ----------------------------
137

138
  # Is the current User the correct User (or is admin mode on)?  Returns true
139
  # or false.  (*NOTE*: this is available to views.)
140
  #
141
  #   <% if check_permission(@object)
142
  #     link_to('Destroy', :action => :destroy_object)
143
  #   end %>
144
  #
145
  def check_permission(obj)
1✔
146
    in_admin_mode? || correct_user_for_object?(obj)
1,618✔
147
  end
148
  # helper_method :check_permission
149

150
  def correct_user_for_object?(obj)
1✔
151
    owned_by_user?(obj) || editable_by_user?(obj) || obj_is_user?(obj)
1,596✔
152
  end
153

154
  def owned_by_user?(obj)
1✔
155
    obj.respond_to?(:user_id) && @user&.id == obj.user_id
1,596✔
156
  end
157

158
  def editable_by_user?(obj)
1✔
159
    obj.try(:can_edit?, @user)
847✔
160
  end
161

162
  def obj_is_user?(obj)
1✔
163
    (obj.is_a?(String) || obj.is_a?(Integer)) && obj.to_i == @user.id
729✔
164
  end
165

166
  # Make sure user is logged in and has posted something -- i.e., not a spammer.
167
  def require_successful_user
1✔
168
    return true if @user&.successful_contributor?
42✔
169

170
    flash_warning(:unsuccessful_contributor_warning.t)
3✔
171
    redirect_back_or_default("/")
3✔
172
    false
3✔
173
  end
174

175
  private :correct_user_for_object?, :owned_by_user?, :editable_by_user?,
1✔
176
          :obj_is_user?
177

178
  # Is the current User the correct User (or is admin mode on)?  Returns true
179
  # or false.  Flashes a "denied" error message if false.
180
  #
181
  #   def destroy_thing
182
  #     @thing = Thing.find(params[:id].to_s)
183
  #     if check_permission!(@thing)
184
  #       @thing.destroy
185
  #       flash_notice "Success!"
186
  #     end
187
  #     redirect_to(:action => :show_thing)
188
  #   end
189
  #
190
  def check_permission!(obj)
1✔
191
    unless (result = check_permission(obj))
284✔
192
      flash_error(:permission_denied.t)
79✔
193
    end
194
    result
284✔
195
  end
196
  alias check_user_id check_permission!
1✔
197

198
  # Is the current User a reviewer?  Returns true or false.  (*NOTE*: this is
199
  # available to views.)
200
  def reviewer?
1✔
201
    result = false
2,851✔
202
    result = @user.in_group?("reviewers") if @user
2,851✔
203
    result
2,851✔
204
  end
205
  # helper_method :reviewer?
206

207
  # Is the current User in admin mode?  Returns true or false.  (*NOTE*: this
208
  # is available to views.)
209
  def in_admin_mode?
1✔
210
    session[:admin]
17,145✔
211
  end
212
  # helper_method :in_admin_mode?
213

214
  # ----------------------------
215
  #  "Private" methods.
216
  # ----------------------------
217

218
  # Create/update the auto-login cookie.
219
  def autologin_cookie_set(user)
1✔
220
    cookies["mo_user"] = {
122✔
221
      value: "#{user.id} #{user.auth_code}",
222
      expires: 1.month.from_now,
223
      same_site: :lax
224
    }
225
  end
226

227
  # Destroy the auto-login cookie.
228
  def clear_autologin_cookie
1✔
229
    cookies.delete("mo_user")
739✔
230
  end
231

232
  # Store User in session (id only).
233
  def session_user_set(user)
1✔
234
    session[:user_id] = user ? user.id : nil
870✔
235
    user
870✔
236
  end
237

238
  # Retrieve the User from session.  Returns freshly loaded User object or nil.
239
  # (Does not check verified status or anything.)
240
  def session_user
1✔
241
    User.safe_find(session[:user_id])
8,433✔
242
  end
243
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc