Mission Net Application: Documentation
Mission Net is a solution for sending messages to people via mobile phone text messages (SMS) and/or email. It was developed especially as a way to get important information (warnings about community unrest etc.) to members of our organization in an unstable country where Internet access is limited, but nearly everyone has a mobile phone. A key aim of the application is that it should be accessible by SMS and email. Users should not only receive messages but should be able to request information, broadcast messages, and change their personal details without having to use the Internet. A second driving aim is that the entire application resides online, so that there is no need for a local server or operator.
See the Features section below for a more complete description.
Important Note: this application is in development, and so is this documentation. Furthermore, this is my first experience in making an app open source, so I’ll probably be making some mistakes along the way. Anyone is welcome to try out the system (which would involve installing and configuring it) but you should use caution if you’re considering it for production. It is not yet an easy-to-install, ready-to-use application, at least if you have no experience putting a Rails application into production. That said, we are currently using it as a real-life application for rapid communication via SMS and email among nearly 200 users in Jos, Nigeria, where the main purpose is dissemination of security information. To date it has only been used quite lightly, so we don’t know how it will perform under a heavier load.
There is not yet a demonstration or sandbox site, but I hope to be able to add one soon. There are some screenshots throughout this document.
If you are interested in setting up a demo site, let me know.
Note that “Mission Net” is a provisional name for this application … it might conflict with some other app, or we might find a better name in the future …
Using Mission Net
Accessing Mission Net via Web Browser
Form View (for creating/editing individuals)
Departure and Arrival Dates
Access Mission Net by Mobile Phone SMS Messages
Access Mission Net by Email
Bugs & problems
Comments and Requests
To Do List
(A Few) Technical Details
Setup (A Sketch)
Deploying to a Server
Under the Hood
- Web-based directory with columns (fields) for name, nationality, phone numbers (2), email addresses (2), emergency contact info, location (drop-down selection plus free text detail field), blood type, willingness to be a blood donor, whether currently in-country, and dates for next departure and arrival.
- Administrator-controlled nested groups. A group can represent an organization, a location, a mailing list, level of access to the database, etc. Any person in the database can be put on any group.
- Ability to send SMS and email messages to one or more groups. Users can access the distribution list via SMS, email, or a web form. For example, a user can send a message to all medical personnel, or everyone in a given area, just by sending a single text message to the application.
- Users can request news updates, with an optional keyword. For example, if a crisis occurs in one area (e.g. Bukuru), a security leader could first broadcast a warning message to everyone alerting them of that fact. Then anyone interested in the conditions at Bukuru could request updates via an SMS like “updates Bukuru”. This feature reduces the problem of having to broadcast all messages to everyone because of not knowing who needs what.
- Users can request directory information via SMS or email. When a user sends “info morgan,” she will get a reply like “Sanchez, Morgan: +44715242049, firstname.lastname@example.org”.
- All messages are logged and viewable (with the right privileges) on the web page. The list also shows the status of each individual sent message, based on the information received from the gateway. Depending on the gateway used, this can include whether the message was accepted into the gateway, whether it was rejected because of errors, and whether it was delivered to a phone (for SMS).
- Pre-configured for two SMS gateway services, Clickatell and Twilio. Others can be added by writing appropriate plugin.
- If a second SMS gateway is defined as an alternate, messages which fail on the primary gateway will be directed to the alternate. (Not every gateway supports every phone number world-wide).
- Messages can include a response tag. If a message is of such importance that it is essential to ensure that each person has received it, the sender can request a confirmation response. Recipients can confirm by SMS or email. The web page shows which recipients have or have not responded.
- Users can generate printable phone & email lists.
- The sender can send a follow-up message which the system will send only to recipients who have not responded.
- Authentication. You don’t need to create another set of user names and passwords, because users can log in to the system using their Facebook or Google accounts. For example, if I normally sign in to my Facebook account with email@example.com, I can use the same email for the Mission Net application. The system will find the user record with the matching email address and log me in as that person..
- Authorization. Each person can be assigned to one or more groups defined by the moderators. Each group can carry one of five privilege levels, ranging from none to administrator, determining what the user can do within the system.
- Users, even those who cannot see the information in the database, can edit their own information online.
- Supports multiple interface languages through simple locale files. Already configured for English and French (but French is not yet well-translated).
Using Mission Net
Accessing Mission Net via Web Browser
If you have Internet access, this is the easiest way to use or manage the system.
Login via your Facebook or Google account. The email address returned by those must match one of the email addresses you have on the database. (For example, if your email address for logging in to Facebook is firstname.lastname@example.org, then you can log in to Mission Net if your primary or secondary email is that address.)
Use the menu on the right to view, add or edit members, groups, or messages. Other tables such as locations and system settings can be accessed by users with appropriate permissions.
To send a message, click on the “Create new message” link in the main menu. Within the new message form, fill in the applicable fields.
- To send an SMS text message, just type in the SMS box, tick the “Send SMS” box, select the groups to receive the message, and click the Save/Send button at the bottom of the form. Note that the message below the group listing will show you how many SMS messages will be sent, given the groups you have selected.
An individual will not receive more than one message, no matter how many groups he or she belongs to, so there is no problem with selecting overlapping groups.
You may optionally add keywords (under advanced options) or type in a longer message in the Email box, which could be useful later if you want to follow up or search for the message later.
- To send an email message, enter a Subject, type your message in the Email box, tick “Send Email”, select the groups, then click the Save/Send button.
- You can send email and SMS messages at the same time; just tick both boxes.
- Currently there is no support for formatting the email message, except that a double line break (extra blank line) separates paragraphs. Use this email feature for sending short, uncomplicated messages.
- If you want your message to be included when someone asks for updates, tick the “News update” box as well, enter some keywords, and choose an expiration period (see below).
- Start by selecting the “Create new message” link.
- To post a news update, just tick that box either by itself or along with others (email and/or SMS). If only the news update is selected, the message will not be sent proactively to anyone but it will be sent on request. If only the email and/or SMS box is selected, then the message will be sent but will not be sent when people request updates.
- Remember that people may request updates by email or SMS, so be sure to enter the information in both of those boxes.
- News updates include an expiration period, after which the update will no longer be sent to those requesting updates. (It will still be visible online.) The default expiration is 6 hours but can be adjusted from 1 to 48 hours. (Does anyone think we need a longer duration?)
- News updates also use the keywords field. Since SMS messages are so limited in size, and we often use abbreviations in them, important words might not be found in a search. For example, if the message includes “Trbl in Bkru,” a search for “Bukuru” would not find it. If you include the important words in the keywords box, though, the message will be found regardless of what is in the actual SMS text.
(Users are simply members when they’re accessing the system. At this point, there is no separate list of “users” as opposed to people listed in the database. )
- Click on the “Members” link on the side menu.
- Click on the “hide menu” link at the top left, if you want, to give more room for the list.
- Most information (too much, in fact) is shown in the listing. A few fields are only visible on the edit (or show) member forms (click on the link on the right side of the row for a given entry). Most of the fields can also be changed directly on the listing without going into the edit form for individuals. You can now hide the less important fields by clicking on the notice to the right of the “Members” title at the top of the table (not shown in the figure). Click again to show them. It’s a bit slow, but it does make viewing easier.
- You can export the entire list to a CSV file if you want to have it available locally for a spreadsheet, to import addresses, etc. Use the Export link at the top right of the list.
The Wife Field
To link a couple, click the Wife field in the husbands row. Choose from the possibilities, which represent all the unmarried people with the same last name. (In the event you need to link a couple with a different last names, start by giving the same last name, link them, and then change the last names to the way they should be.)
Form View (for creating/editing individuals)
- To add a new member, click on the “Create new” link at the top right, and fill in the form as shown below (the same form is used both for creating and for updating members).
- To add members to groups, you can either edit the user (and select multiple groups from the list on that form) or edit the group (selecting multiple members for a given group).
- Phone numbers should all be in the full international format, without a plus, e.g. for Nigeria a number might be 2348033854268.
Departure and Arrival Dates
The departure and arrival dates recorded for each member, besides being possibly useful information in themselves, are used to determine when someone is “in-country” (being “in-country” just means that the person will be included in group email and SMS broadcasts). (The system looks through all the records early each morning and updates their “in-country” fields. You can use the dates in any way that makes sense:
- A departure date alone, with no arrival date, means that someone is leaving in the future.
- An arrival date alone means that someone is arriving in the future, implying that they are currently out of the country.
- An arrival date plus a later departure date implies a period when the person will be in the country (since they are departing after they arrive)
- A departure date plus a later arrival date implies a period when someone will be out of the country.
The main advantage of this system is that you can define the dates in advance, and the system will know each day who is leaving or arriving. Otherwise to really keep up-to-date you would have to manually select and unselect the in-country field on every day that someone comes or goes.
The system will not change the in-country status when something does not make sense. For example, if on the one hand you list someone as being in the country, while on the other you show their departure date as in the past, the system won’t change anything. Perhaps in the future it will warn you, or perhaps not!
Groups have two functions. First, groups are used to select message recipients. Create any groups you need, select the members for each one, then use the groups for sending messages. (Presently, you can not assign individuals to receive messages, only groups.)
Second, groups determine the roles (privilege levels) of users on the system. When viewing the list of groups, you can select which roles apply to which groups. Note that the roles have an order (none < limited < member < moderator < administrator); if you select one level for a group, the lower levels will automatically be included.
Groups do not need to include a role. For example, if you have a set of people who should receive messages but not be able to log on to the system at all, don’t give that group any role. If you need to allow some of those people to have higher privileges, either create a new group for them or add them to an existing group that contains the role you want. A person’s effective role is the highest role in any of the groups they belong to. For example, if someone belongs to group A which has only a “limited” role, and also to group B which has a moderator role, her effective role will be moderator.
NB: All the data in the database, including groups and members, is shared. Thus in a situation where more than one organization is using the same installation, users need to be careful, cooperative and considerate about how they define and use groups. For example, if three organizations share the database, “staff” might not be a good group name.
- Click on the “Groups” link on the side menu to view/edit groups.
- Groups are nested (hierarchical) so a given group can have a parent and children. Anyone listed in a child group (sub-group) is considered to belong to any ancestor groups as well. So, for example, you could have a group named “Office staff,” with sub-groups “finance” and “personnel” (so “finance” and “personnel” both list “Office staff” as their parent). Put the finance people into “finance” and the personnel people into “personnel,” and no one in “Office staff.” Then, when you send a message to “Office staff”, everyone will receive the message.
- Group abbreviations are important because they’re used in SMS messages. Keep them as short as you can, though they should be memorable as well.
Here are the system’s rules about roles:
- Administrators can do anything.
- Moderators can do almost anything, but can’t access the main site settings or change members’ administrator status (i.e. they can’t make someone an administrator or remove that role).
- Members can view almost anything, but can only change their own information.
- Limited members can only change their own information and can’t view others’.
[The privileges of different roles can be adjusted through the CanCan interface. The file to change is app/models/ability.rb.]
Access Mission Net by Mobile Phone SMS Messages
One of the most important reasons for the existence of this system is the need to be operate without an Internet connection, which will never be available to everyone and will sometimes be available to no one. Therefore, one goal is to make as much functionality as possible available for ordinary mobile phones using simple SMS text messaging.
Users communicate with the system by sending an SMS containing a command and possibly options and a message to store or forward. The case (upper or lower) of commands (and options??) does not matter. Spaces are used to separate the elements, which is why a group abbreviation cannot contain a space (only the first part would be seen).
Currently, these commands are available:
d group message
deliver to group (currently, a single request can only target a single group)
d alerts Warning that there could be trouble tomorrow so be careful.
send the user a list of groups marked as “primary”
send list of commands
send information on the requested directory entry, based on name fields
info Jack Gordon
posts message as a news update
report Heavy traffic near stadium.
updates keyword limit
(keyword and limit are optional)
send current updates. If a keyword is given, search for messages containing it. If limit is given, return no more than that number of messages.
updates traffic 3
confirm receipt of message with number msg-id. The optional reply-message (up to one line of text) will be stored in the database under the original message. Currently, the reply-message is not delivered to the sender of the original message.
!21 Thanks for the info.
!21 All safe at home (e.g. in response to a message requesting that everyone reply with their location and status)
If the system receives a message from a member and it does not contain one of these commands, then
- If the member was contacted in the past 6 hours, then it is assumed he or she is replying to the last contact. His message to the system will be forwarded to the sender of the the last message he received. In other words, if Jack sends out a message to everyone at 9 AM, and Jill sends back a reply to the system at 9:05 AM, then her reply will be forwarded to Jack.
- If the member (e.g. Jill) has not been contacted recently, then her message will not be forwarded and she will receive an error message reminding her to contact people directly.
[More explanation: The system is not designed to handle two-way traffic, for two reasons. First, it will generally cost more to send a message to the system (international SMS) than directly to another member. Second, unlike email, SMS messages have no “Reply-to” field. There is no way to know who an incoming message is intended for unless it contains a reference to an outgoing message, as in the “confirm receipt” message (see table above). Furthermore, a forwarded message no longer contains the original phone number, so the recipient will not know who it is from unless the information is added into the body of the message.]
Access Mission Net by Email
[Need to expand this a bit but here are the basics.]
You can configure an incoming email address. You must be sending from one of your registered addresses.
Subject line is not needed
Body can be like the SMS commands except that updates and groups are not yet implemented. Command “d” sends SMS to groups, “email” sends email to groups, and “d+email” or “email+d” sends both email and SMS. Differences from the “d” command sent by SMS: (1) more than one group can be specified, with spaces between them (2) a colon must follow the last (or only) group. So you can have
d alerts: Blah blah blah Sends SMS to alerts group
d+email alerts directors: Blah blah blah Sends SMS & email to alerts & directors
email members: Message to everyone... Sends email (not SMS) to members group
The colon is needed so that the program can distinguish the group names from the start of the message.
You should get a confirmation message saying that your broadcast message has been sent.
Updating the directory by email
You can use email to update the information listed in the database (directory). Simply include lines like
change Adam Wolf 0808-888-8888 email@example.com
The only formatting requirements are that the name be the first thing after the change command and that the phone number cannot contain spaces. The system will do its best to find the matching name even if you give only the first or last name. The phone number will be normalized when stored. [To date, only a single change command should be sent in one email].
When your email reaches the system, it will be checked for consistency. If the name identifies a unique person and you have the required privileges to update the person’s data, the system will return to you a verification email describing the changes to be made. If those are correct, simply reply to the email (just click “reply” and send the message).
If more than one person matches the name, or if there are other problems, the system will email an explanation back to you.
Select the Reports menu item to generate concise, printable listings of information. The only report type available so far is the directory, a list of email addresses and phone numbers. You can view the whole list on the Web browser, which is more convenient than using the normal Members view, or you can download a printable (PDF) version. Select which groups you want to include and whether you want a list sorted by location, by name, or both reports.
Bugs & problems
Just add a description of the issue you’re having
- Initial comma in list of groups in messages listing.
- SentMessage records are not being deleted when their parent message is deleted
- “Private” flag does not prevent phone/email from being shown on the members list view. Fixed in the list view but the data may still leak through other channels -- needs investigating & testing.
- (This is a problem only for development, not operation:) The Redis initialization looks for the environment variable in production mode, and that variable is defined on Heroku but not the development machine. The problem is that assets precompilation is also done in production mode, so the compilation crashes. Workaround is renaming file or commenting out the lines while compiling, but don’t forget to fix it before pushing to production platform!
Comments and Requests
- Is there a way to hide the XYZ Groups so that only I or another designated XYZ person could edit? Maybe it would not be too hard to make a role such as “sub-moderator” or “group moderator” that is able to moderate a given group. Maybe the parent of a group that confers the role “sub-moderator” would be the scope of the sub-moderator’s privileges.
To Do List
These are in no particular order
Function & usability
- Keep expanding the documentation.
- Video or slide introduction to use
- Allow directory updates to be made by email (and SMS?)
- Send email to people when their SMS numbers fail to work (mainly to remind them that the phone number needs to be updated).
- Server-to-browser messaging (to inform of incoming SMS and email)
- Work on response speed
- Ability to send messages to an arbitrary set of members
- Improve appearance, styling! (then add predefined style packages, or some color selectors …)
- Allow SMS message to deliver to multiple groups (‘d alerts+sec’)
- Templates for mobile devices
- Server to mobile-device (or browser) messaging as a way of broadcast (an alternative to SMS)
- Twitter feed??
- Incorporate domains, isolated sets of members that would allow separate organizations to use the same site without compromising security. Technically not hard but could be an administrative tangle
- Add ability to log in via user-name/password (low priority?)
Stability & Generalizability
These features are required or useful for setting up new installations.
- Make Redis database optional (currently it is assumed)
- More testing
(A Few) Technical Details
Framework: Ruby on Rails version 3.2, with ActiveScaffold.
Database: PostgreSQL (The app is also configured to include Redis (in-memory DB), but this is not much, currently only for caching the current user role.)
Source repository: http://github.com/MikeBlyth/mission_net
SMS Gateways already configured: Clickatell, Twilio
Setup (A Sketch)
This is currently just my guess at how to install this application on a new site. You can use if as a guideline, but someone with experience in Rails should be around to help!
Just a thought: You might be able to deploy directly from the source (on github) to a server (such as Heroku), but I don’t have any experience doing that and there may still be some customization needed, which will be easier to do on your local machine than on a server.
I’m using Linux Ubuntu 10.04 for development. You can follow most of the same instructions on Windows, and probably Mac, but Windows is much slower with Rails development than Linux, in my experience (though this was with Rails ver 3.0; 3.2 may be faster).
- Start with a fresh installation of Ubuntu (other distros may work also).
- Start at the command line (open a shell prompt)
- Install Git source manager
- Install Ruby (I’m using 1.9.2p0, but newer versions will probably work also. See also Three Ways of Installing Ruby
- Install Rails (just a matter of “gem install rails”)
- Create the source folder for this application:
- go to the folder into which you want to create the application folder. Your home folder is fine. The following step will create a new folder “mission_database”.
- git clone git://github.com/MikeBlyth/mission_database.git
- If you want to use a folder name other than “mission_database,” add that name after the clone command above, e.g.
git clone git://github.com/MikeBlyth/mission_database.git myfolder
- Go into the project folder you just created, i.e.
- Install all the dependencies used by the application: bundle install
- Install the PostgreSQL database (Heroku currently requires using PostgreSQL. If you’re using a different host or if they’ve changed their policy, use MySQL or whatever database you prefer; see the Rails documentation for how to do this).
- Edit the database definitions found in config/database.yml.example, and save as the new file config/database.yml (see Configuring a Database in the Rails Guides)
- Initialize the database: rake db:setup
This creates the database and seeds it with initial data.
- Run the local server: rails server
This process stays in the foreground by default, so you can see the log, so you may want to put it into its own instance of the shell (command line window).
- Open a browser and point it to “http://localhost:3000”. You should get a page that offers to set up an administrator, since your database of members is empty. Enter and save the information.
- Now you should be logged in (or able to log in) to your local system.
Most of the parameters that need customization are available from the running program itself, but currently (and possibly while you’re following these instructions) there are still some that need to be changed in the source files.
- Database definition: see above (editing the database.yml file)
- Edit config/application_settings.yml, if it exists, and enter your own organization’s name, administrator email, etc.
- The file config/site_settings.yml, if it exists, contains gateway and service settings, some email addresses, etc. You can edit it and enter the values you wish in the “default:” lines, or you can simply edit the same data from the web interface by selecting Settings (or something like it!) from the main menu. These settings include:
- SendGrid username and password if you’re using SendGrid for your email (but note: the app is not currently set up to use SendGrid so you’ll have to modify the code if that hasn’t been done by the time you’re reading this).
- Credentials for SMS gateway providers such as Twilio and Clickatell. You do not need both.
- Twilio Background job provider (“DelayedJob” on Heroku, or “IronWorker”) [currently only used with Twilio outgoing SMS, since Clickatell is already fast, needing only a single API call to send up to 300 messages].
- Notifications: a list of email addresses, comma separated, to which various notifications will be sent (changes of address, new locations, etc.). This might not be implemented yet.
- Parameters for how many items to keep in the log, messages, and sent-messages folders.
- Edit config/initializers/private_parameters.rb.example and fill in the parameters you need. These include:
- OmniAuth authentication. This is the system that lets you piggyback on Google, FaceBook, or other servers for authentication. That means the users can log in without having to know another password just for this system. See http://www.omniauth.org/ for information.
This Mission Net application is already configured to use Google and FaceBook for authentication, so you just have to get API keys for those and plug them into the proper places in the private_paremeters file. You can add other “strategies” as well but will have to follow the instructions at the OmniAuth site.
The List of Strategies describes which “sites” (loosely speaking) can be used, such as Facebook and Google, and links to instructions on using them. The current setup for Google uses their OAuth2, and requires you to get an API Key at https://code.google.com/apis/console/. The info on getting a key for FaceBook is at http://developers.facebook.com/docs/authentication. Of course, these sites change from time to time so you may have to hunt for the instructions.
- Heroku API Key. This is needed if your app is deployed on Heroku and you want to use DelayedJob to run background tasks like sending out SMS messages. All you need is to check on your accounts page to copy the key. This is the easiest option to set up.
- IronWorker credentials. The other built-in option for running background tasks is IronWorker. Simply go to that site, sign up for a free account, and enter the credentials into this file. (You will still have to save your “worker” to your IronWorker account, see below).
- SMTP outgoing email account information. Get this from your email provider. The online Rails Guides has a section on configuring this for a Gmail account.
A number of maintenance tasks are included in the package (under lib/tasks) and can be run on a fixed schedule or as needed. These are run with the rake command. They include
- update_in_country: using each person’s arrival and departure dates, update their in-country (on-location) status. This should probably be scheduled to run every day.
- clean_old: remove old entries from application log, messages and sent messages files.
- unduplicate_group_members: If members have become added to a group more than once, the names may be listed twice in some places, though sending messages will not be affected. This probably won’t happen in the current setup, but if it does, just run this task.
- (though of course it will not fix the cause of the problem!)
- resync_max_ids: it’s possible for the database to lose track of the last-used (highest) id number for the records in a table. When that happens, trying to add a record results in a duplicate key violation since, for example, the DB may try to add a record with the ID of 10 rather than 85, while record 10 already exists. The resync_max_ids task simply sets last ID in each table to the highest ID value in that table, resolving the situation. As with unduplicate_group_members, this issue should not occur in the first place but, if it does, this tool can be handy to get the DB working again until the underlying bug is fixed.
To run one of these commands manually, simply run them from the command line in the application folder, e.g.
If you are going to use IronWorker to do background jobs, you need to upload the “workers” first. Currently only an SMS sender (twilio_multi_worker) exists but in the future an emailer may be added. If voice is used, this should also be done in the background.
The iron_worker program on your local computer should have been installed already as it is part of the Gemfile which you ran with bundle. You still need to install your credentials, though, so follow the instructions on the Iron.io site. Currently, this requires creating a file named iron.json which looks like
"token": "YOUR TOKEN",
"project_id": "YOUR PROJECT ID"
and placing it in either in your home folder or in the folder that contains the workers.
The program code for workers is found in lib/workers. To upload twilio_multi_worker, just type
iron_worker upload twilio_multi_worker
Mission Net incorporates Rails’ I18n API, making it is easy to add a new locale, which would include mainly translations of messages in a new language but also the date and time formats. Simply copy the config/locales/en.yml file to one representing the new locale (e.g. es.yml for Spanish), and update all the strings with the proper translations. See the French file (fr.yml) as an example. Presently, there is also a separate fr_datetime.yml file from a third party. If you are adding a new language, you might find such a package for that language so that you don’t have to add every detail yourself.
Rspec is used for running a suite of tests on the app. The tests are not perfect and don’t cover all the code, but they’re better than nothing. To run them, type
on the command line in the application’s main folder.
Deploying to a Server
- Get an account on Heroku and follow their instructions for deploying your app. Once you’ve gotten the account and installed the Heroku local application, getting the application running on Heroku should be as simple as
- git push heroku master
- heroku run rake db:setup
- heroku ps:restart
However, you’ll have to consult the Heroku documentation to get up-to-date instructions.
I don’t know about these, so you’ll have to do it yourself.
Under the Hood
A disorganized hodge-podge of bits of information about the program as they arise …
OpenAuthorization providers Facebook and Google are used. Others can be added. Authentication is based on email addresses. When the user clicks on “Connect using your Facebook account,” the authenticator connects to Facebook and verifies that the user is logged in (or can log in) to Facebook, and returns an email address. If the application finds a matching email address in the database of members, it assigns the owner of that address to be the current user. If more than one person shares an email address, the one with the highest privilege is assigned to be the user.
This whole area may need to be reworked, but this is the current setup.
NB: there is some confusion because of the mixed terminology I started with and have not yet systematized. “Member” can mean (a) the model representing the people who are listed in the database or (b) a role (privilege level). So a member in sense (a) might not have the role (b) of member, but might have a limited role or no role. That is, there can be entries in the database for people (or entities) that have no privileges to access the database. Another confusing area is that “users” (those accessing the database) are actually members (in sense (a)). There is no separate model for application users as opposed to members (a) contained in the database.
Presently, though, the system uses 4 pre-defined roles or levels of authorization: administrator, moderator, member, and limited. These are expressed in the code in symbol form, e.g. :administrator, :limited, and so on. They are ranked in the order given, so that administrator will have all the privileges of the levels it under it and so on. [To do: Currently ranking occurs in several places: Moderator.recalc_highest_role, Moderator.roles_include?, and Ability.initialize, possibly others! It would be good to formalize a single location for ranking, whether by creating a separate class for roles or a single method to compare them.]
Important methods include
- login_allowed(user_email). (in app/models/session_helper.rb) More than one member may have the same email address, usually because they’re spouses. This method returns the member with the highest privileges among those which have user_email for an address and who have at least member privilege (i.e. it excludes those with limited and no privileges). If you want to allow limited-privilege users to log in, then uncomment the line that will include them.
- Member.role. The highest role held by the user (users belong to the Member class) based on the groups the user belongs to. Example: “if user.role == :moderator”
- Member.roles_include?. Whether user has privileges at the given level or higher. For example, “if user.roles_include?(:moderator) ….” Note that ‘roles’ is plural.
The privileges of different roles can be adjusted through the CanCan interface. The file to change is app/models/ability.rb.
Simplified diagram of how incoming and outgoing SMS messages are processed. Click on image link to see zoomable image.
 The application uses Rails 3.2; source repository: http://github.com/MikeBlyth/mission_net
 Authorizations are currently hard-coded into the program, using the pre-defined groups Administrators, Moderators, Members, and Limited (with “no privileges” being the default absence of any of the others). More fine-grained authorization controls may be added later.
 A spouse field would be more straightforward conceptually, but as far as I could see, it would be easier to implement it this way. For one thing, it’s not necessary to specify everyone’s sex. For another, a one-way relationship (husband has a wife, wife belongs to a husband) is simpler than each member of the couple having a spouse.
 Naturally, you can use “in-country” to mean something other than that; whatever you call it, messages will not be delivered unless the person has that field selected (ticked). You can change the displayed name of the column in app/controllers/members_controller.rb by adding the line “config.columns[:in_country].label = 'On location' “ (or your desired label) to the active_scaffold configuration section at the top of the file.
 Besides serving as a verification step, this back-and-forth email prevents any third party from attacking the database by spoofing an authorized email. Only the person controlling the valid email account will receive the verification email, and the encrypted key prevents anyone else from exploiting that email.