<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mvenkat3</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mvenkat3"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Mvenkat3"/>
	<updated>2026-08-11T08:05:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2109._Completion/Progress_view&amp;diff=138538</id>
		<title>CSC/ECE 517 Spring 2021 - E2109. Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021_-_E2109._Completion/Progress_view&amp;diff=138538"/>
		<updated>2021-04-01T00:25:52Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: Created page with &amp;quot;='''Problem Statement'''= A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading of these reviews to ensure students write quality reviews, helping them learn more about the assignment by looking at their peers' work. In addition, Expertiza allows for metareviews, which are reviews the authors of the original work write for the reviews of their original work. This author feedback is useful for grading the reviews because it indicates how helpful this review was to the authors of the original work. The objective of this project is to add metareview or author feedback information to the review report page, which shows a summary of all the reviews written by the students for an assignment.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
&lt;br /&gt;
The aim of this project is to build this into the system. We need an additional column in the 'Review Report' page for reviews which shows the calculation of the author feedback. This will help instructor's to know how the reviews proved useful to the authors/team. The aim of this project is to integrate the author feedback column in the summary page&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021&amp;diff=138537</id>
		<title>CSC/ECE 517 Spring 2021</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021&amp;diff=138537"/>
		<updated>2021-04-01T00:24:17Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Final Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OSS Projects ==&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2100. Tagging report for students]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2101. Refactor questionnaires controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2106. Fix view in student_task/list page]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2103. Refactor response_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2107. Refactor grades_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2102. Refactor quiz_questionnaires_controller.rb]]&lt;br /&gt;
* [[CSE/ECE 517 Spring 2021 - E2108. Impersonate_controller.rb]]&lt;br /&gt;
* [[CSE/ECE 517 Spring 2021 - E2105. Track the time students look at other submissions]]&lt;br /&gt;
* [[CSE/ECE 517 Spring 2021 - E2104.  Email notification to reviewers and instructors]]&lt;br /&gt;
&lt;br /&gt;
== Final Projects ==&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2110. Regulate changing of rubrics while projects are in progress]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2111. Refactor github metrics integration]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2115. Mentor management for assignments without topics]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2113. Enhancements to review grader]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2021 - E2109. Completion/Progress view]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138177</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138177"/>
		<updated>2021-03-20T01:12:35Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* E. Changes made to implement Anonymized View */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====D. check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====E. do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====F. Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138176</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138176"/>
		<updated>2021-03-20T01:12:10Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* D. do_main_operation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====D. check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====E. do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====E. Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138175</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138175"/>
		<updated>2021-03-20T01:12:00Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* C. check_if_special_char */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====D. check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====D. do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====E. Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138174</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138174"/>
		<updated>2021-03-20T01:11:23Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Changes made to implement Anonymized View */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C. check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====D. do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====E. Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138173</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138173"/>
		<updated>2021-03-20T01:10:58Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* do_main_operation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C. check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====D. do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138172</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138172"/>
		<updated>2021-03-20T01:10:29Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* check_if_special_char */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C. check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138171</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138171"/>
		<updated>2021-03-20T01:10:11Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* overwrite_session */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====C.overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138170</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138170"/>
		<updated>2021-03-20T01:09:48Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* display_error_msg */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====B. display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138169</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138169"/>
		<updated>2021-03-20T01:09:30Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* check_if_user_impersonateable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====A.check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138168</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138168"/>
		<updated>2021-03-20T01:07:35Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* overwrite_session */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
'''Initial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138167</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138167"/>
		<updated>2021-03-20T01:05:43Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Problem Solution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Changes made to implement Anonymized View=====&lt;br /&gt;
Initially, while using the anonymized view to impersonate the account: student8597, we received the following error.&lt;br /&gt;
[[File: anon_without_space_err.png|1000px]]&lt;br /&gt;
This occured as the following method was initially splitting the name using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user_id = anonymized_name.split(' ’)[1]&lt;br /&gt;
    user = User.find_by(id: user_id)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus while doing the above function, what happens is that the student’s name is searched for a space and the ID is obtained as the numerics after the space, which isn’t the case for our user’s names (eg: student8597). Thus we had to modify this method under app/models/user.rb to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.real_user_from_anonymized_name(anonymized_name)&lt;br /&gt;
    user = User.find_by(name: anonymized_name)&lt;br /&gt;
    return user&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code snippet, what we are instead doing is, directly finding the user from the anonymized_name which in the errored case as in the figure above was ’’student8597'’.&lt;br /&gt;
Apart from these changes, we also had to include the following statements in various parts of the impersonate_controller.rb file to ensure the the previously written test for anonymous view doesn’t break anywhere.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
        user = User.anonymized_view?(session[:ip]) ? User.real_user_from_anonymized_name(params[:impersonate][:name]) : user = user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138166</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138166"/>
		<updated>2021-03-20T00:58:25Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Testing Functionalities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
======A. Testing Navigation Bar======&lt;br /&gt;
Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
    request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
    @params = { user: { name: student1.name } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
    @params = { impersonate: { name: student2.name } }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student2&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======B. Testing Anonymized User======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it ‘instructor should be able to impersonate a user with their anonymized name’ do&lt;br /&gt;
    allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
    allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
    allow(User).to receive(:anonymized_view?).and_return(true)&lt;br /&gt;
    allow(User).to receive(:real_user_from_anonymized_name).with(“Student30”).and_return(student1)&lt;br /&gt;
    request.env[“HTTP_REFERER”] = “http://www.example.com”&lt;br /&gt;
    @params = { user: { name: “Student30&amp;quot; } }&lt;br /&gt;
    @session = { user: instructor }&lt;br /&gt;
    post :impersonate, @params, @session&lt;br /&gt;
    expect(session[:super_user]).to eq instructor&lt;br /&gt;
    expect(session[:user]).to eq student1&lt;br /&gt;
    expect(session[:original_user]).to eq instructor&lt;br /&gt;
    expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138165</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138165"/>
		<updated>2021-03-20T00:44:58Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* B. Testing the impersonate functionality from the Navigation Bar: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
note: The above screenshot was captured after instructor6 impersonated student8597, you can also try to impersonate student8597&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138164</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138164"/>
		<updated>2021-03-20T00:37:59Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* B. Testing the impersonate functionality from the Navigation Bar: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: nav_bar1.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: nav_bar2.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
======C. Testing Anonymized View====== &lt;br /&gt;
   1.Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2.Go to Manage --&amp;gt; Anonymized view &lt;br /&gt;
&lt;br /&gt;
[[File: Enter_anonymized_view.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   3.Check for impersonate functionality using Manage --&amp;gt; Impersonate User with user account: student8597.&lt;br /&gt;
&lt;br /&gt;
[[File: Manage_impersonate_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: manage_impersonated_user-anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
   4.Check for impersonate functionality using navigation bar on top right, with user account: student8598.&lt;br /&gt;
&lt;br /&gt;
[[File: bar_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File: bar_user_pg_anon.png |1000px|]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Manage_impersonated_user-anon.png&amp;diff=138162</id>
		<title>File:Manage impersonated user-anon.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Manage_impersonated_user-anon.png&amp;diff=138162"/>
		<updated>2021-03-20T00:21:17Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: Mvenkat3 uploaded a new version of File:Manage impersonated user-anon.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Bar_user_pg_anon.png&amp;diff=138161</id>
		<title>File:Bar user pg anon.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Bar_user_pg_anon.png&amp;diff=138161"/>
		<updated>2021-03-20T00:20:57Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Enter_anonymized_view.png&amp;diff=138160</id>
		<title>File:Enter anonymized view.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Enter_anonymized_view.png&amp;diff=138160"/>
		<updated>2021-03-20T00:20:36Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Bar_anon.png&amp;diff=138159</id>
		<title>File:Bar anon.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Bar_anon.png&amp;diff=138159"/>
		<updated>2021-03-20T00:20:17Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Manage_impersonated_user-anon.png&amp;diff=138158</id>
		<title>File:Manage impersonated user-anon.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Manage_impersonated_user-anon.png&amp;diff=138158"/>
		<updated>2021-03-20T00:16:57Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Manage_impersonate_anon.png&amp;diff=138157</id>
		<title>File:Manage impersonate anon.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Manage_impersonate_anon.png&amp;diff=138157"/>
		<updated>2021-03-20T00:16:39Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Nav_bar1.png&amp;diff=138156</id>
		<title>File:Nav bar1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Nav_bar1.png&amp;diff=138156"/>
		<updated>2021-03-20T00:16:24Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Nav_bar2.png&amp;diff=138155</id>
		<title>File:Nav bar2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Nav_bar2.png&amp;diff=138155"/>
		<updated>2021-03-20T00:16:02Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Anon_without_space_err.png&amp;diff=138154</id>
		<title>File:Anon without space err.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Anon_without_space_err.png&amp;diff=138154"/>
		<updated>2021-03-20T00:15:10Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138148</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138148"/>
		<updated>2021-03-20T00:08:00Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* B. Testing the impersonate functionality from the Navigation Bar: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File:navigation.png|200px|thumb|left|alt text]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138145</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138145"/>
		<updated>2021-03-20T00:06:20Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* B. Testing the impersonate functionality from the Navigation Bar: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
[[File: navigation1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Navigation2.png&amp;diff=138138</id>
		<title>File:Navigation2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Navigation2.png&amp;diff=138138"/>
		<updated>2021-03-20T00:03:31Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Navigation1.png&amp;diff=138136</id>
		<title>File:Navigation1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Navigation1.png&amp;diff=138136"/>
		<updated>2021-03-20T00:02:40Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138134</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138134"/>
		<updated>2021-03-19T23:59:31Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
#The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
#The impersonate functionality using the navigation bar.&lt;br /&gt;
#The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
======A. Testing Impersonate functionality from the Manage tab and Revert functionality:======&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
======B. Testing the impersonate functionality from the Navigation Bar:======&lt;br /&gt;
&lt;br /&gt;
In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the navigation bar on top right of the screen and enter student8598 and click on impersonate.&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138133</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138133"/>
		<updated>2021-03-19T23:50:39Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The UI testing of this project can be performed on three fronts:&lt;br /&gt;
&lt;br /&gt;
A. The normal impersonate functionality from the Manage tab and Revert functionality.&lt;br /&gt;
B. The impersonate functionality using the navigation bar.&lt;br /&gt;
C. The anonymized view's impersonate functionality(both from the Manage bar as well as the navigation bar).&lt;br /&gt;
&lt;br /&gt;
You can use the following details of various users to test the heirarchies and the impersonations between them.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User Name to enter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Super Administrator&lt;br /&gt;
| super_administrator2&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6753&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7609&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student7610, 7603&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To test out the three fronts follow the steps mentioned below under each sub-heading:&lt;br /&gt;
&lt;br /&gt;
A. Testing Impersonate functionality from the Manage tab and Revert functionality:&lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
B. Testing the impersonate functionality from the Navigation Bar:&lt;br /&gt;
&lt;br /&gt;
   In order to perform the following testing:&lt;br /&gt;
&lt;br /&gt;
   1. Login as instructor using username: instructor6 and password: password.&lt;br /&gt;
   2. Go on to the Manage tab --&amp;gt; Impersonate user.&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138101</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138101"/>
		<updated>2021-03-19T21:22:28Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Testing Functionalities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;br /&gt;
&lt;br /&gt;
1. Instructor should be able to impersonate a user while already impersonating a user but from navigation bar.&lt;br /&gt;
This test is to ascertain the functionality of the user being able to impersonate another user(obeying hierarchy) through the navigation bar on the top right hand corner. This is to test the rectification of the previous issue, where this functionality was broken. Here, we test the functionality by first logging in as the instructor(id:2) and then first impersonating a student1 using the main menu’s Manage tab. This redirects us to the student1’s page. Now, from the navigation bar, we try to impersonate another student, student2. This test finally checks if the session is true and the parameters are correct.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it 'instructor should be able to impersonate a user while already impersonating a user but from nav bar' do&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student1.name).and_return(student1)&lt;br /&gt;
            allow(User).to receive(:find_by).with(name: student2.name).and_return(student2)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student1).and_return(true)&lt;br /&gt;
            allow(instructor).to receive(:can_impersonate?).with(student2).and_return(true)&lt;br /&gt;
            request.env[&amp;quot;HTTP_REFERER&amp;quot;] = &amp;quot;http://www.example.com&amp;quot;&lt;br /&gt;
            @params = { user: { name: student1.name } }&lt;br /&gt;
            @session = { user: instructor }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            # nav bar uses the :impersonate as the param name, so let make sure it always works from there too.&lt;br /&gt;
            @params = { impersonate: { name: student2.name } }&lt;br /&gt;
            post :impersonate, @params, @session&lt;br /&gt;
            expect(session[:super_user]).to eq instructor&lt;br /&gt;
            expect(session[:user]).to eq student2&lt;br /&gt;
            expect(session[:original_user]).to eq instructor&lt;br /&gt;
            expect(session[:impersonate]).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138097</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138097"/>
		<updated>2021-03-19T20:53:12Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing Functionalities ===&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138092</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138092"/>
		<updated>2021-03-19T20:35:20Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # Revert to original account&lt;br /&gt;
        else&lt;br /&gt;
          if !session[:super_user].nil?&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          # E1991 : check whether instructor is currently in anonymized view&lt;br /&gt;
          if User.anonymized_view?(session[:ip])&lt;br /&gt;
            # get real name when instructor is in anonymized view&lt;br /&gt;
            user = User.real_user_from_anonymized_name(params[:impersonate][:name])&lt;br /&gt;
          else         &lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          end&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138091</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138091"/>
		<updated>2021-03-19T20:22:42Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2018 OSS Program for Spring 2021, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&amp;lt;/b&amp;gt;&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
         '''session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              '''return'''&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            '''return'''&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138063</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138063"/>
		<updated>2021-03-19T15:40:45Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2002 OSS Program for Spring 2020, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&amp;lt;/b&amp;gt;&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
         '''session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              '''return'''&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            '''return'''&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
[[File:impersonate.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Impersonate.jpg&amp;diff=138062</id>
		<title>File:Impersonate.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Impersonate.jpg&amp;diff=138062"/>
		<updated>2021-03-19T15:38:29Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138061</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138061"/>
		<updated>2021-03-19T15:28:41Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* About Impersonate Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2002 OSS Program for Spring 2020, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&amp;lt;/b&amp;gt;&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
         '''session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              '''return'''&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            '''return'''&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138060</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138060"/>
		<updated>2021-03-19T15:26:14Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2002 OSS Program for Spring 2020, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Expertiza allows administrators, instructors and Teaching Assistants to impersonate other users like a student. This allows the impersonator to view assignments, deadlines and submissions of other students.&lt;br /&gt;
The rules to impersonating a user is, the impersonator has to be an ancestor of the impersonate.&lt;br /&gt;
The hierarchy of impersonation is as follow:&lt;br /&gt;
super administrator -&amp;gt; Administrator -&amp;gt; Instructor -&amp;gt; Teaching Assistant -&amp;gt; Student &lt;br /&gt;
Note: impersonation cannot happen within the same level of hierarchy. &lt;br /&gt;
For Example, a Super Administrator can impersonate any user apart from other Super Administrators, an Administrator can impersonate Instructors, TA, Students and not other Admins and so on.  &lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
&lt;br /&gt;
*All functions related to impersonate controller were present in a single method which is 79 lines long.&lt;br /&gt;
&lt;br /&gt;
*Presence of repetitive code (Around 40 repetitive lines)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&amp;lt;/b&amp;gt;&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
         '''session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Block nesting &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Too many return statements &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              '''return'''&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            '''return'''&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The impersonation can be done by using an impersonate bar which currently does not allow initial impersonation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above.&lt;br /&gt;
&lt;br /&gt;
===About Impersonate Controller===&lt;br /&gt;
Expertiza allows the administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. For example, an instructor impersonating a student’s account can view their assignments, stage deadlines, peer reviews and anything else that the student can view. &lt;br /&gt;
&lt;br /&gt;
One thing to be noted is that most of these users can only impersonate users for whom they are a parent. For example, instructor6 is a parent of student3841 and not student3836; as a result, instructor6 can impersonate only 3841.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138049</id>
		<title>CSE/ECE 517 Spring 2021 - E2108. Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138049"/>
		<updated>2021-03-19T14:20:26Z</updated>

		<summary type="html">&lt;p&gt;Mvenkat3: Created page with &amp;quot;This wiki page describes the work done under E2002 OSS Program for Spring 2020, in the CSC/ECE 517 course.      ===About Expertiza===  [http://expertiza.ncsu.edu/ Expertiza] i...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the work done under E2002 OSS Program for Spring 2020, in the CSC/ECE 517 course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza is a complete instructor-student usage website where the instructor can assign assignments, deadlines, grades, etc that is required for the course. Similarly, the students can use this website to perform the tasks required as part of the course like project or assignments submission, forming groups and collaborating with them, as well as reviewing projects and teammates.&lt;br /&gt;
&lt;br /&gt;
This project focuses on a specific feature of expertiza which allows administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. &lt;br /&gt;
The demonstration for the feature is as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Impersonate guide.jpg|figure 1|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
&lt;br /&gt;
[[File:Non impersonate.jpg|figure 2|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
[[File:Impersonated view.jpg|figure 3|frame|center]]&lt;br /&gt;
         &lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The aim of the project is to refactor the impersonate controller. The pre-existing code had the following major issues.&lt;br /&gt;
*All functions related to impersonate controller were present in a single method ( from figure 4a and 4b)&lt;br /&gt;
*Presence of repetitive code ( from figure 4a and 4b)&lt;br /&gt;
*3 levels of block nesting (from figure 5)&lt;br /&gt;
* Too many return statements (from figure 6) &lt;br /&gt;
[[File:initial code1.jpg| figure 4a| frame|center]]&lt;br /&gt;
[[File:initial code2.jpg| figure 4b| frame|center]]&lt;br /&gt;
[[File:code climate3.jpg| figure 5| frame|center]]&lt;br /&gt;
[[File:code climate2.jpg| figure 6| frame|center]]&lt;br /&gt;
&lt;br /&gt;
This project is focused on resolving the issues mentioned above. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Impersonate Controller===&lt;br /&gt;
Expertiza allows the administrators, instructors or teaching assistants to impersonate another user (like a student) and access their account. For example, an instructor impersonating a student’s account can view their assignments, stage deadlines, peer reviews and anything else that the student can view. &lt;br /&gt;
&lt;br /&gt;
One thing to be noted is that most of these users can only impersonate users for whom they are a parent. For example, instructor6 is a parent of student3841 and not student3836; as a result, instructor6 can impersonate only 3841.&lt;br /&gt;
&lt;br /&gt;
===Impersonate functionality navigation===&lt;br /&gt;
1. Instructor login: username -&amp;gt; instructor6, password -&amp;gt; password&lt;br /&gt;
&lt;br /&gt;
when logged in as an instructor, under the manage option in the ribbon as in Figure 1, select impersonate user. &lt;br /&gt;
Upon redirected to impersonate page, enter the account which needs to be impersonated. It impersonates that user provided that user can be impersonated. Now a new button called revert appears on the ribbon as in figure 3, this can be used to revert the impersonation and return to the instructor profile.&lt;br /&gt;
&lt;br /&gt;
===Problem Solution===&lt;br /&gt;
The above-mentioned issues have been tackled by refactoring the impersonate controller by splitting into many smaller methods which are later called by the main impersonate controller.&lt;br /&gt;
&lt;br /&gt;
The following are the refactored new methods that help in tackling the issue1 apart from each being specifically for some issue rectification:&lt;br /&gt;
*check_if_user_impersonateable&lt;br /&gt;
*display_error_msg&lt;br /&gt;
*overwrite_session&lt;br /&gt;
*check_if_special_char&lt;br /&gt;
*do_main_operartion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====check_if_user_impersonateable=====&lt;br /&gt;
This method plays the main role in tackling issue3 - 3 levels of block nesting apart from issue1.&lt;br /&gt;
&lt;br /&gt;
'''Intial Code'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
''' After recfactoring - Moved to separate method'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def check_if_user_impersonateable &lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          if !@original_user.can_impersonate? user&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;	    &lt;br /&gt;
            temp&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)          &lt;br /&gt;
          else &lt;br /&gt;
            overwrite_session&lt;br /&gt;
	  end&lt;br /&gt;
    else &lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
            user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    overwrite_session&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=====display_error_msg=====&lt;br /&gt;
This method is used to tackle issues1, 2 and 4. All the error message related code is moved to this method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def display_error_msg&lt;br /&gt;
    if params[:user]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
    elsif params[:impersonate]&lt;br /&gt;
          @message = &amp;quot;No user exists with the name '#{params[:impersonate][:name]}'.&amp;quot;    &lt;br /&gt;
    else	 &lt;br /&gt;
          if params[:impersonate].nil?&lt;br /&gt;
            @message = &amp;quot;You cannot impersonate '#{params[:user][:name]}'.&amp;quot;&lt;br /&gt;
          else&lt;br /&gt;
            if !params[:impersonate][:name].empty?&lt;br /&gt;
              @message = &amp;quot;You cannot impersonate '#{params[:impersonate][:name]}'.&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              @message = &amp;quot;No original account was found. Please close your browser and start a new session.&amp;quot;&lt;br /&gt;
           end &lt;br /&gt;
       end&lt;br /&gt;
    end&lt;br /&gt;
    rescue Exception =&amp;gt; e&lt;br /&gt;
      flash[:error] = @message&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====overwrite_session=====&lt;br /&gt;
This method reduces the number of return statements used in impersonate controller, apart from reducing the size of the controller.&lt;br /&gt;
&lt;br /&gt;
====== Initial Code======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if params[:impersonate].nil?&lt;br /&gt;
        # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
        if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
        user = User.find_by(name: params[:user][:name])&lt;br /&gt;
        if user&lt;br /&gt;
          unless original_user.can_impersonate? user&lt;br /&gt;
            flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
          AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = message&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # Impersonate a new account&lt;br /&gt;
        if !params[:impersonate][:name].empty?&lt;br /&gt;
          # check if special chars /\?&amp;lt;&amp;gt;|&amp;amp;$# are used to avoid html tags or system command&lt;br /&gt;
          if warn_for_special_chars(params[:impersonate][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
          if user&lt;br /&gt;
            unless original_user.can_impersonate? user&lt;br /&gt;
              flash[:error] = &amp;quot;You cannot impersonate #{params[:user][:name]}.&amp;quot;&lt;br /&gt;
              redirect_back&lt;br /&gt;
              return&lt;br /&gt;
            end&lt;br /&gt;
            AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = original_user&lt;br /&gt;
          else&lt;br /&gt;
            flash[:error] = message&lt;br /&gt;
            redirect_back&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
====== After Refactoring - Moved to a separate method and accessed through the adapter method do_main_operation======&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     def overwrite_session&lt;br /&gt;
    #if not impersonatable, then original user's session remains&lt;br /&gt;
    if params[:impersonate].nil?&lt;br /&gt;
          user = User.find_by(name: params[:user][:name])&lt;br /&gt;
          session[:super_user] = session[:user] if session[:super_user].nil?&lt;br /&gt;
      	  AuthController.clear_user_info(session, nil)&lt;br /&gt;
          session[:original_user] = @original_user&lt;br /&gt;
          session[:impersonate] = true&lt;br /&gt;
          session[:user] = user&lt;br /&gt;
    else&lt;br /&gt;
    #if some user is to be impersonated, their session details are overwritten onto the current to impersonate	&lt;br /&gt;
&lt;br /&gt;
          if !params[:impersonate][:name].empty?&lt;br /&gt;
	    user = User.find_by(name: params[:impersonate][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = user&lt;br /&gt;
            session[:impersonate] =  true&lt;br /&gt;
            session[:original_user] = @original_user&lt;br /&gt;
          else&lt;br /&gt;
            user = User.find_by(name: params[:user][:name])&lt;br /&gt;
	    AuthController.clear_user_info(session, nil)&lt;br /&gt;
            session[:user] = session[:super_user]&lt;br /&gt;
            user = session[:user]&lt;br /&gt;
            session[:super_user] = nil&lt;br /&gt;
          end&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====check_if_special_char=====&lt;br /&gt;
This code is used to reduce one functionality performed under the impersonate controller. This method checks to see if the given username is acceptable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if warn_for_special_chars(params[:user][:name], &amp;quot;Username&amp;quot;)&lt;br /&gt;
          redirect_back&lt;br /&gt;
          return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====do_main_operation=====&lt;br /&gt;
This like an adapter method that is used to interface the impersonate method with display_error_msg and check_if_user_impersonatable. One main purpose to do this is to make the methods flexible for change apart from reducing the number of lines from the impersonate controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def do_main_operation(user)&lt;br /&gt;
     if user&lt;br /&gt;
      check_if_user_impersonateable&lt;br /&gt;
     else&lt;br /&gt;
      display_error_msg&lt;br /&gt;
     end&lt;br /&gt;
  end  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Plan ===&lt;br /&gt;
The project can be tested from the UI as follows. &lt;br /&gt;
&lt;br /&gt;
Checking if impersonating a user is working &lt;br /&gt;
   1. Input: User that can be impersonated &lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;student5890&amp;quot; &lt;br /&gt;
   Now you will be able to see that user &amp;quot;student5890&amp;quot; has been impersonated.&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 1.jpg| figure 7| frame|center]]&lt;br /&gt;
[[File:imp test 2.jpg| figure 8| frame|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 9| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   2. Input: Reverting from impersonated account &lt;br /&gt;
 &lt;br /&gt;
       We will have the user &amp;quot;student5890&amp;quot;  impersonated.&lt;br /&gt;
      - Press the blue revert button at the top of the window&lt;br /&gt;
      Now you will have returned to the instructor profile&lt;br /&gt;
&lt;br /&gt;
[[File:imp test 4.jpg| figure 10| frame|center]]&lt;br /&gt;
[[File:imp test 8.jpg| figure 11| frame|center]]&lt;br /&gt;
&lt;br /&gt;
   3. Input: User that cannot be impersonated&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;super_administrator2&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user cannot be impersonated. &lt;br /&gt;
[[File:imp test 6.jpg| figure 12| frame|center]]&lt;br /&gt;
[[File:imp test 5.jpg| figure 13| frame|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   4. Input: User that does not exist&lt;br /&gt;
     - Login as the instructor (username -&amp;gt; instructor6 , password -&amp;gt; password &lt;br /&gt;
     - Under &amp;quot;Manage&amp;quot; tab, select &amp;quot;impersonate user&amp;quot; option &lt;br /&gt;
     - In the form, give the user ID as &amp;quot;studentstudent&amp;quot;&lt;br /&gt;
   Now you will be able to see a message being displayed on the screen, that tells that the given user does not exist.&lt;br /&gt;
[[File:imp test 7.jpg| figure 14| frame|center]]&lt;br /&gt;
[[File:imp test 3.jpg| figure 15| frame|center]]&lt;/div&gt;</summary>
		<author><name>Mvenkat3</name></author>
	</entry>
</feed>