Summary
Imagine you are a Linux system administrator who is tasked with user account management and who must keep persistent records of the user ID for the account, their name, their employment status, personal contact information, and other details, including some that are unknown today, but that may need to be added as the company evolves. In this program, we will set up some of the groundwork using Ruby classes and modules.
There will be two classes, one module, and a main program that tests the classes and their methods.
UserAccount Class
Let's start by thinking of UserAccount as a class. The UserAccount class should be primarily concerned with the fields that are commonly used as arguments to the useradd command and its related commands in the Linux system (usermod, for instance). At the very least, it should have the account user ID in an easy-to-maintain format, the group(s) to which it belongs, the GECOS field, the home directory (usually needed but not always), and the initial password.
The attributes of the UserAccount class are as follows. The RO (read-only) and RW (read-write) designations indicate whether you need a getter and a setter, or just a getter method.
Attribute Name |
Attribute Type (Comments) |
Access |
user_id |
String |
RW |
gecos |
String |
RW |
groups |
Array of Strings |
RW |
home_dir |
String (empty String indicates no home directory) |
RW |
password |
String (in plain text for now) |
RW |
account_owners |
Array of Person (see Person Class below) |
RW |
access_granted_date |
Time |
RW |
access_suspended_date |
Time |
RW |
initialize method
Since all attributes are RW, it is possible to construct objects of the class without defining an initialize method, but we will provide our own initialize method that sets groups and account_owners to an empty array. It should not accept any parameters at this point.
Person Class
User accounts are generally associated with people, so it would seem we need a class called Person as well. The first design problem we face is how to model the relationship of owner(s) to accounts. For instance, John Adams may be the single person associated with a Linux account jadams, in which case it might make sense to create a base class called Person and make UserAccount a derived class. But, the root account on a given host may be managed by a team of Admins. In that case, the relationship of UserAccount to Person is a one-to-many relationship.
So, we will create the Person class as a standalone class that captures personal information and associate it to the UserAccount as an array of Persons. [Since we initialized account_owners to an empty Array, there is no problem with filling these in after building the UserAccount class.]
The Person class must have the following attributes:
Attribute Name |
Attribute Type (Comments) |
Access |
id |
Fixnum |
RO |
first_name |
String |
RW |
middle_initial |
String (may be full middle name as well, optional) |
RW |
last_name |
String |
RW |
suffix |
String (Jr., Sr., III, etc., may be blank) |
RW |
department_id |
Fixnum |
RW |
role |
String (E, C, G, or O for employee, contractor, guest, or other) |
RW |
phone_number |
String (formatted 111-222-3333, with optional ext) |
RW |
email_address |
String (formatted person@acme.com) |
RW |
initialize method
Since we have at least one RO attribute, it is necessary to initialize the class with that attribute. Provide an initialize method that takes one argument, which can be any Fixnum you like for testing. Make sure you can display that attribute, but not alter it in your test code.
GeneratePassword Module
The third component of this program is a module that we will call GeneratePassword that will create a plain-text password conforming to our in-house password complexity rules. Eventually, that module will also be capable of generating an encrypted string suitable for use with the useradd command, but not for this version.
It will contain one method called generate_plain_text that takes no parameters and returns an eight-character random String consisting of lower-case letters and at least one each of upper-case letters, digits, and special symbols. For example, careL3&s would be a valid password String. You may choose to treat all letters as one big group by making an Array out of two Ranges, a-z, and A-Z. It doesn't matter in what order the special characters or digits are included, so you may wish to hard-code the order.
For special characters, use this group:
special = ['−', '%', '&', '@', '#', '!' ]
HINT: An easy way to generate 1 or more random characters from an Array such as the one shown is the sample method of Arrays. Given the array above, ['−', '%', '&', '@', '#', '!' ].sample would pick one of the characters while sample(2) would pick two, and so on.
As to how we use the method generate_plain_text, the typical way is to include that module in the class definition where it's to be used. Use the include directive to make generate_plain_text available in the UserAccount class.
For this project, though, we also want to make this module potentially independent of any object. When you define the module, add a line module_function :generate_plain_text after defining the actual method generate_plain_text. This will allow you to test the method by calling it directly on the module, as in GeneratePassword.generate_plain_text in your test driver code if you wish.
Test Driver
As you create the classes and modules above, add code that tests the creation and modification of the classes and all methods.
DescriptionIn this final assignment, the students will demonstrate their ability to apply two ma
Path finding involves finding a path from A to B. Typically we want the path to have certain properties,such as being the shortest or to avoid going t
Develop a program to emulate a purchase transaction at a retail store. Thisprogram will have two classes, a LineItem class and a Transaction class. Th
1 Project 1 Introduction - the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of
1 Project 2 Introduction - the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of