<?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=Skrish28</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=Skrish28"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Skrish28"/>
	<updated>2026-05-12T18:50:32Z</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=138846</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=138846"/>
		<updated>2021-05-01T00:58:14Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
Expertiza allows users to complete peer reviews on fellow students' work. However, not all peer reviews are helpful, and some are more useful than others. Therefore, the application allows for the project's authors to provide feedback on the peer review, this is called &amp;quot;author feedback.&amp;quot; The instructors have no easy way to access the author feedback while grading peer reviews, which would be a useful feature to have since this shows how helpful the peer review actually was to the group that received it. Thus, making the author feedback more accessible is the aim of this project. However, a group in 2018 was tasked with this project as well, and most of the functionality appears to have been implemented already, but that is in an older version of Expertiza. Our primary task is then to follow their implementation, refactor any code that may require it, make the suggested improvements that were left in their project feedback and make the feature compatible with the latest beta branch of Expertiza. Secondary tasks are to make the author feedback column toggleable and to refactor the function that averages author feedbacks so that it reuses existing code that exists somewhere in Expertiza already.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
#Our primary goal is to take the author feedback column functionality from the 2018 branch and update it so that it merges successfully with the current beta branch.&lt;br /&gt;
#In the 2018 branch, there is an author feedback column to the review report, but the previous team's submission added new code to calculate the average. However, this most likely already exists somewhere else in the system, and so we will identify where that functionality exists and refactor the code to reuse it to follow the DRY principle.&lt;br /&gt;
#Part of the 2018 group's feedback said that the review report UI began to look somewhat crowded in its appearance. However, there is often no author feedback, and so the column for that should be made toggleable. So we will make it so that the column is dynamic and will only be present if there is author feedback to display. The user could then toggle the column to show or hide that information depending on their own preference.&lt;br /&gt;
&lt;br /&gt;
='''Design'''=&lt;br /&gt;
Below is the current implementation of the page we are going to edit on the beta branch. It can be seen that the &amp;quot;author feedback&amp;quot; column is not present in this view at all.&lt;br /&gt;
&lt;br /&gt;
[[File:beta_view.PNG |1500px|]]&lt;br /&gt;
&lt;br /&gt;
Here is the 2018 group's version of the page we are editing. It has the &amp;quot;author feedback&amp;quot; column as well as the necessary functionality. However, the user interface has clearly changed since 2018, and therefore, there will likely be merge conflicts between their branch and the current beta branch. Part of our task would then be to resolve those merge conflicts and port the functionality back over to the most recent beta branch. (Sourced from this [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view link])&lt;br /&gt;
&lt;br /&gt;
[[File:impl_screenshot.png |1500px|]]&lt;br /&gt;
&lt;br /&gt;
Currently, in the 2018 group's branch, the entries in the &amp;quot;Score awarded/Avg. score&amp;quot; and &amp;quot;Author Feedback Score&amp;quot; columns contain a lot of missing entries. Though, this does not appear to be the case in the most recent beta branch available in 2021. Therefore, we would add this filter (i.e. code that removes the missing entries represented by the dashes) to the missing entries available in the beta branch to the 2018 group's branch code.&lt;br /&gt;
&lt;br /&gt;
In addition, the 2018 group's branch has the author feedback in its own column in-between &amp;quot;AVG score&amp;quot; and &amp;quot;Metrics&amp;quot;. Instead, we will move it under the same header column &amp;quot;Scores&amp;quot; as seen in the current beta branch, just to the right of the &amp;quot;AVG Score&amp;quot; column. To accommodate for this additional column being introduced, the &amp;quot;Team reviewed&amp;quot; column width would be reduced a bit so that the &amp;quot;Scores&amp;quot; column renders approximately at the same location on the page.&lt;br /&gt;
&lt;br /&gt;
Below is the final product of our implementation. As can be seen, some columns that had unnecessarily large amounts of space given to their width e.g. reviewer and team reviewed, have been reduced to accommodate the new author feedback column. There is also still ample space for the assign grade and write comments column to be expanded.&lt;br /&gt;
&lt;br /&gt;
[[File:author_feedback1.png |1500px|]]&lt;br /&gt;
&lt;br /&gt;
='''Files Changed'''=&lt;br /&gt;
The below files were expected to be edited by our group to complete this project:&lt;br /&gt;
#app/views/reports/_review_report.html.erb&lt;br /&gt;
#app/controllers/review_mapping_controller.rb&lt;br /&gt;
#app/models/on_the_fly_calc.rb&lt;br /&gt;
#app/views/reports/response_report.html.haml&lt;br /&gt;
#app/views/reports/_team_score.html.erb&lt;br /&gt;
&lt;br /&gt;
However, the below files had to be edited (or added) in order to implement the author feedback column:&lt;br /&gt;
#app/helpers/report_formatter_helper.rb&lt;br /&gt;
#app/helpers/review_mapping_helper.rb&lt;br /&gt;
#app/models/on_the_fly_calc.rb&lt;br /&gt;
#app/views/reports/_review_report.html.erb&lt;br /&gt;
#app/views/reports/_team_score_author_feedback.html.erb&lt;br /&gt;
&lt;br /&gt;
In the report_formatter_helper.rb file, an attribute had to be added to the helper (that is later mixed in with the reports_controller). This attribute gives the controller access to the model's author feedback scores that have been calculated.&lt;br /&gt;
&lt;br /&gt;
The review_mapping_helper.rb file required an older method to be once again introduced, this method is called &amp;quot;get_each_round_score_awarded_for_review_report&amp;quot;. It is required to properly read and display the computed author feedback scores from the hash they are stored in. Another method that is similar to it, &amp;quot;get_awarded_review_score&amp;quot;, could not be used as it causes an exception to be thrown; this is due to the fact that the &amp;quot;get_awarded_review_score&amp;quot; method does not accommodate for when the hash does not contain the key it is trying to access (specifically, it is unable to handle when the &amp;quot;reviewer_id&amp;quot; does not exist in the hash's set of keys).&lt;br /&gt;
&lt;br /&gt;
The on_the_fly_calc.rb file only required the expected changes as introduced in our implementation plan. However, one additional method, called &amp;quot;feedback_questionnaire_id&amp;quot; had to be added in order for the &amp;quot;calc_feedback_scores_sum&amp;quot; method (that is also in the same file) to work. This method used to exist else where in an older version of Expertiza, located in the assignment.rb model, but it is not needed beyond the scope of &amp;quot;calc_feedback_scores_sum&amp;quot;, so it exists with private access in the on_the_fly_calc.rb file.&lt;br /&gt;
&lt;br /&gt;
The _review_report.html.erb file had to be modified - the width of the other columns was reduced to make room for the author feedback column, the column header was added, and the necessary call to the author feedback column partial was also introduced. &lt;br /&gt;
&lt;br /&gt;
Finally, a new file called _team_score_author_feedback.html.erb, was added to the repository. This file is the partial required to render the author feedback column, and is a reintroduction of the 2018 group's _team_feedback_score.html.erb file.&lt;br /&gt;
&lt;br /&gt;
='''Implementation Plan'''=&lt;br /&gt;
Like the 2018 group, we plan to add three methods to the on_the_fly_calc.rb file in Models. These methods are:&lt;br /&gt;
#compute_author_feedback_scores&lt;br /&gt;
#calc_avg_feedback_score(response)&lt;br /&gt;
#calc_feedback_scores_sum&lt;br /&gt;
&lt;br /&gt;
The feedbacks are stored in the ResponseMaps table and are queried using the assignment_id/reviewer who gave the response/reviews(responses) in each round in the 'compute_author_feedback_scores' method. The method iterates through all the rounds done during the review process, and calls the 'calc_avg_feedback_score' method, providing a &amp;quot;response&amp;quot; argument. The response argument is the review a team provides for the author's work. Lastly, in order to obtain the final average score for a particular review (response) that the authors (team) have gotten, they obtain a sum of the feedback scores from each of the authors and divide it by the total number of feedbacks that were obtained. These methods have already been implemented by the 2018 group and are included here again for the reader's convenience.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
def compute_author_feedback_scores&lt;br /&gt;
    @author_feedback_scores = {}&lt;br /&gt;
    @response_maps = ResponseMap.where('reviewed_object_id = ? &amp;amp;&amp;amp; type = ?', self.id, 'ReviewResponseMap')&lt;br /&gt;
    rounds = self.rounds_of_reviews&lt;br /&gt;
    (1..rounds).each do |round|&lt;br /&gt;
      @response_maps.each do |response_map|&lt;br /&gt;
        response = Response.where('map_id = ?', response_map.id)&lt;br /&gt;
        response = response.select {|response| response.round == round }&lt;br /&gt;
        @round = round&lt;br /&gt;
        @response_map = response_map&lt;br /&gt;
        calc_avg_feedback_score(response) unless response.empty?&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @author_feedback_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
def calc_avg_feedback_score(response)&lt;br /&gt;
  # Retrieve the author feedback response maps for the teammates reviewing the review of their work.&lt;br /&gt;
  author_feedback_response_maps = ResponseMap.where('reviewed_object_id = ? &amp;amp;&amp;amp; type = ?', response.first.id, 'FeedbackResponseMap')&lt;br /&gt;
  author_feedback_response_maps.each do |author_feedback_response_map|&lt;br /&gt;
    @corresponding_response = Response.where('map_id = ?', author_feedback_response_map.id)&lt;br /&gt;
    next if @corresponding_response.empty?&lt;br /&gt;
    calc_feedback_scores_sum&lt;br /&gt;
  end&lt;br /&gt;
  # Divide the sum of the author feedback scores for this review by their number to get the&lt;br /&gt;
  # average.&lt;br /&gt;
&lt;br /&gt;
  if !@author_feedback_scores[@response_map.reviewer_id].nil? &amp;amp;&amp;amp;&lt;br /&gt;
      !@author_feedback_scores[@response_map.reviewer_id][@round].nil? &amp;amp;&amp;amp;&lt;br /&gt;
      !@author_feedback_scores[@response_map.reviewer_id][@round][@response_map.reviewee_id].nil? &amp;amp;&amp;amp;&lt;br /&gt;
      !author_feedback_response_maps.empty?&lt;br /&gt;
    @author_feedback_scores[@response_map.reviewer_id][@round][@response_map.reviewee_id] /= author_feedback_response_maps.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
def calc_feedback_scores_sum&lt;br /&gt;
  @respective_scores = {}&lt;br /&gt;
  if !@author_feedback_scores[@response_map.reviewer_id].nil? &amp;amp;&amp;amp; !@author_feedback_scores[@response_map.reviewer_id][@round].nil?&lt;br /&gt;
    @respective_scores = @author_feedback_scores[@response_map.reviewer_id][@round]&lt;br /&gt;
  end&lt;br /&gt;
  author_feedback_questionnaire_id = feedback_questionnaire_id(@corresponding_response)&lt;br /&gt;
  @questions = Question.where('questionnaire_id = ?', author_feedback_questionnaire_id)&lt;br /&gt;
  # Calculate the score of the author feedback review.&lt;br /&gt;
  calc_review_score&lt;br /&gt;
  # Compute the sum of the author feedback scores for this review.&lt;br /&gt;
  @respective_scores[@response_map.reviewee_id] = 0 if @respective_scores[@response_map.reviewee_id].nil?&lt;br /&gt;
  @respective_scores[@response_map.reviewee_id] += @this_review_score&lt;br /&gt;
  # The reviewer is the metareviewee whose review the authors or teammates are reviewing.&lt;br /&gt;
  @author_feedback_scores[@response_map.reviewer_id] = {} if @author_feedback_scores[@response_map.reviewer_id].nil?&lt;br /&gt;
  @author_feedback_scores[@response_map.reviewer_id][@round] = {} if @author_feedback_scores[@response_map.reviewer_id][@round].nil?&lt;br /&gt;
  @author_feedback_scores[@response_map.reviewer_id][@round] = @respective_scores&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, they calculate the average with a custom implementation that most likely exists somewhere else in Expertiza already as suggested by the instructors. As part of our project, we will identify where that functionality exists, and either reuse it or extend it so that it can be reused here instead. Though, we will first implement the functionality as the previous group did, and then slowly perform our refactor to ensure functionality is not broken by the refactoring process.&lt;br /&gt;
&lt;br /&gt;
Since we will need to modify the user interface to introduce the author feedback column, we expect to add a column within the .erb files in the views folder that were identified above. These files were selected as they were the files necessary for the previous group to implement their UI changes.&lt;br /&gt;
&lt;br /&gt;
They also add a 'calculate_avg_score_by_feedback' method to the controller for the file 'app/controllers/review_mapping_controller.rb'. The following method was written by the previous team to calculate the average scores for the feedback given by authors for the reviews of their work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
 def calculate_avg_score_by_feedback(question_answers, q_max_score)&lt;br /&gt;
      # get score and summary of answers for each question&lt;br /&gt;
      # only include divide the valid_answer_sum with the number of valid answers&lt;br /&gt;
&lt;br /&gt;
      valid_answer_counter = 0&lt;br /&gt;
      question_score = 0.0&lt;br /&gt;
      question_answers.each do |ans|&lt;br /&gt;
        # calculate score per question&lt;br /&gt;
        unless ans.answer.nil?&lt;br /&gt;
          question_score += ans.answer&lt;br /&gt;
          valid_answer_counter += 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if valid_answer_counter &amp;gt; 0 and q_max_score &amp;gt; 0&lt;br /&gt;
        # convert the score in percentage&lt;br /&gt;
        question_score /= (valid_answer_counter * q_max_score)&lt;br /&gt;
        question_score = question_score.round(2) * 100&lt;br /&gt;
      end&lt;br /&gt;
      question_score&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, it exists in the controller level logic, and perhaps isn't required to exist there. It is likely better for this method to be moved to this controller's corresponding model, and we will do so during our project to make the code follow the principles of MVC.&lt;br /&gt;
&lt;br /&gt;
='''Test Plan'''=&lt;br /&gt;
The 2018 group wrote a RSpec test when they wrote their function to calculate the author feedback scores. It was located in the on_the_fly_calc_spec.rb file and the method they wrote was called 'compute_author_feedback_scores'. Below is the snippet of the RSpec test that they wrote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
describe '#compute_author_feedback_score' do&lt;br /&gt;
    let(:reviewer) { build(:participant, id: 1) }&lt;br /&gt;
    let(:feedback) { Answer.new(answer: 2, response_id: 1, comments: 'Feedback Text', question_id: 2) }&lt;br /&gt;
    let(:feedback_question) { build(:question, questionnaire: questionnaire2, weight: 1, id: 2) }&lt;br /&gt;
    let(:questionnaire2) { build(:questionnaire, name: &amp;quot;feedback&amp;quot;, private: 0, min_question_score: 0, max_question_score: 10, instructor_id: 1234) }&lt;br /&gt;
    let(:reviewer1) { build(:participant, id: 2) }&lt;br /&gt;
    let score = {}&lt;br /&gt;
    let(:team_user) { build(:team_user, team: 2, user: 2) }&lt;br /&gt;
    let(:feedback_response) { build(:response, id: 2, map_id: 2, scores: [feedback]) }&lt;br /&gt;
    let(:feedback_response_map) { build(:response_map, id: 2, reviewed_object_id: 1, reviewer_id: 2, reviewee_id: 1) }&lt;br /&gt;
&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      allow(on_the_fly_calc).to receive(:rounds_of_reviews).and_return(1)&lt;br /&gt;
      allow(on_the_fly_calc).to receive(:review_questionnaire_id).and_return(1)&lt;br /&gt;
    end&lt;br /&gt;
    context 'verifies feedback score' do&lt;br /&gt;
      it 'computes feedback score based on reviews' do&lt;br /&gt;
        expect(assignment.compute_author_feedback_scores).to eq(score)&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;
== UI Testing ==&lt;br /&gt;
The UI testing, isn't much of a functionality, but is rather the change in the view of the report page by the intructor. For anyone to test the UI, the following steps would be a suitable guide:&lt;br /&gt;
# First login to the expertiza website with ''Username'' as '''instructor6''' and ''password'' as '''password'''.&lt;br /&gt;
# Next click on Manage and tab on top left of the screen and click '''Anonymized View'''.&lt;br /&gt;
# Once we get into ananoymized view, click on '''Assignments'''.&lt;br /&gt;
# After the assignment list loads up, on any given assignment, eg: Final Project Documentation, navigate to the right side and search for the icon with a person on it and says Review report.&lt;br /&gt;
# Click on that icon. This will take you to another page where there is a button '''Report View'''. Click on that.&lt;br /&gt;
# This will navigate you to the report page as seen above and you will be able to view the Author's Feedback column and score obtained for every student.&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
#https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&lt;br /&gt;
#https://docs.google.com/document/d/1uzr5pybVKYr_K1Q8wSd4t-Id9nqTt3k1ePseDjY-RJg/edit#&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138489</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=138489"/>
		<updated>2021-03-30T02:04:31Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: &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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
=====G. Changes to fix the broken impersonate Navigation Bar=====&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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 from a RSPec end ===&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;
This test verifies the functionality that is available with from the Anonymized view. It checks for the impersonation from both the ends - Through the Manage tab as well as the Navigation Bar.&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;br /&gt;
&lt;br /&gt;
=== Useful Links ===&lt;br /&gt;
The following are the links to the useful pages in understanding this project(as of Spring 2021)&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/Expertiza_documentation] - General wiki describing the Expertiza project.&lt;br /&gt;
* [https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos] - Youtube page to expertiza tasks.&lt;br /&gt;
* [https://github.com/expertiza/expertiza] - GitHub repo that maintains code for Expertiza.&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/Main_Page/CSC/CSC_517_Spring_2020_Refactor_impersonate_controller] - Spring 2020's wiki for the refactoring of impersonate controller.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1687] - Spring 2020's pull request for the refactored impersonate controller.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1907] - Pull request for the work done in Spring 2021.&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138204</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=138204"/>
		<updated>2021-03-20T01:50:47Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* B. Testing Anonymized User */&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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
=====G. Changes to fix the broken impersonate Navigation Bar=====&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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 from a RSPec end ===&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;
This test verifies the functionality that is available with from the Anonymized view. It checks for the impersonation from both the ends - Through the Manage tab as well as the Navigation Bar.&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138203</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=138203"/>
		<updated>2021-03-20T01:49:25Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
=====G. Changes to fix the broken impersonate Navigation Bar=====&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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 from a RSPec end ===&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138202</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=138202"/>
		<updated>2021-03-20T01:48:47Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
=====G. Changes to fix the broken impersonate Navigation Bar=====&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138201</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=138201"/>
		<updated>2021-03-20T01:48:11Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138200</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=138200"/>
		<updated>2021-03-20T01:47:47Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* F. 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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138198</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=138198"/>
		<updated>2021-03-20T01:45:54Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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;
&lt;br /&gt;
''Note: You cannot login as a super_administrator2, as the login details are unknown. However, we have included ways to test the inability for a lower hierarchy memeber to impersonate the super_administrator.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ User details&lt;br /&gt;
! Hierarchy of user&lt;br /&gt;
! User account 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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138197</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=138197"/>
		<updated>2021-03-20T01:41:52Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* Impersonate functionality navigation */&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;
===How Impersonating works?===&lt;br /&gt;
Basic login details: (Instructor login is only available) 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138195</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=138195"/>
		<updated>2021-03-20T01:40:15Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* D. 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;
Older version consisted only of the following snippet of code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_if_special_char&lt;br /&gt;
    if params[:user]&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;
In the current code, the following code is added to accomodate the navigation bar funcionality of impersonate.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if params[:impersonate]&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;
    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;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138192</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=138192"/>
		<updated>2021-03-20T01:34:49Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* G. Changes to fix the broken impersonate 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;
=====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;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#D. check_if_special_char|D. check_if_special_char]])&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138190</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=138190"/>
		<updated>2021-03-20T01:33:58Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* F. 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;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer [[#Section D&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138187</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=138187"/>
		<updated>2021-03-20T01:30:15Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* F. 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;
&lt;br /&gt;
======G. Changes to fix the broken impersonate Navigation Bar======&lt;br /&gt;
The broken part of this refactoring project, as compared to the previous year’s, was the Navigation bar on the top right part of the screen. As mentioned earlier, in order to impersonate we have two methods:&lt;br /&gt;
Using the Manage --&amp;gt; Impersonate User&lt;br /&gt;
Using the Navigation Bar.&lt;br /&gt;
However, as far as the previous submission goes, the Navigation bar’s functionality wasn’t complete. The aim of this refactoring is to also fix this and enable the impersonate functionality to work from there as well.&lt;br /&gt;
The previous submission broke while trying to use the Navigation bar for impersonation because of the wrong passage of params between the views and controllers. In order to make the impersonate from the Manage --&amp;gt; Impersonate User work, the form that was rendered was the expertiza/app/views/impersonate/start.html.erb. Here, the field filled was :user. And was then checkd for in the impersonate_controller.rb.&lt;br /&gt;
However, the Navigation Bar makes use of the :impersonate symbol to pass the impersonated user’s name and other details to the controller, for which no check was included earlier. Thus, there was no way to procure a user from the navigation bar. In the current submission this is fixed by including the following check in the impersonate_controller.rb/check_if_special_char:&lt;br /&gt;
&lt;br /&gt;
The check_if_special_char is a function which checks if the Username entered is valid or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def check_if_special_char&lt;br /&gt;
    if params[:user]&lt;br /&gt;
      if warn_for_special_chars(params[:user][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if params[:impersonate]&lt;br /&gt;
      if warn_for_special_chars(params[:impersonate][:name], “Username”)&lt;br /&gt;
        redirect_back&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, in the above code snippet, there is a check for the :impersonate’s params, which earlier was missing(Refer part C of this section).&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138131</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=138131"/>
		<updated>2021-03-19T23:41:57Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138130</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=138130"/>
		<updated>2021-03-19T23:40:11Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! 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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138129</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=138129"/>
		<updated>2021-03-19T23:39:53Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! Instructor&lt;br /&gt;
| instructor7319&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138128</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=138128"/>
		<updated>2021-03-19T23:39:36Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| instructor7319&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138126</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=138126"/>
		<updated>2021-03-19T23:36:55Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! Admin&lt;br /&gt;
| administrator968&lt;br /&gt;
|-&lt;br /&gt;
! Admin&lt;br /&gt;
| administrator967&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| intructor6&lt;br /&gt;
|-&lt;br /&gt;
! Instructor&lt;br /&gt;
| instructor7319&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6962&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant7120&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138123</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=138123"/>
		<updated>2021-03-19T23:35:41Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! Instructor&lt;br /&gt;
| instructor7319&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant6962&lt;br /&gt;
|-&lt;br /&gt;
! TA&lt;br /&gt;
| teaching_assistant7120&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138117</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=138117"/>
		<updated>2021-03-19T23:19:40Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! 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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSE/ECE_517_Spring_2021_-_E2108._Impersonate_controller.rb&amp;diff=138105</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=138105"/>
		<updated>2021-03-19T22:50:30Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* 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;
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;
! Student&lt;br /&gt;
| student5890&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student8598&lt;br /&gt;
|-&lt;br /&gt;
! Student&lt;br /&gt;
| student8597&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>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138059</id>
		<title>CSC/ECE 517 Spring 2021/E2108.Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138059"/>
		<updated>2021-03-19T15:22:40Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, '''Bold''' we are creating this!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
print('Hi!')&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138058</id>
		<title>CSC/ECE 517 Spring 2021/E2108.Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138058"/>
		<updated>2021-03-19T15:22:18Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, '''Bold''' we are creating this!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'''print('Hi!')'''&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138057</id>
		<title>CSC/ECE 517 Spring 2021/E2108.Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138057"/>
		<updated>2021-03-19T15:22:05Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, '''Bold''' we are creating this!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print('Hi!')&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138056</id>
		<title>CSC/ECE 517 Spring 2021/E2108.Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138056"/>
		<updated>2021-03-19T15:21:42Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, '''Bold''' we are creating this!&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021&amp;diff=138048</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=138048"/>
		<updated>2021-03-19T14:14:09Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: /* OSS 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 - 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;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138047</id>
		<title>CSC/ECE 517 Spring 2021/E2108.Impersonate controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2021/E2108.Impersonate_controller.rb&amp;diff=138047"/>
		<updated>2021-03-19T14:09:59Z</updated>

		<summary type="html">&lt;p&gt;Skrish28: Created page with &amp;quot;Hi, we are creating this!&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, we are creating this!&lt;/div&gt;</summary>
		<author><name>Skrish28</name></author>
	</entry>
</feed>