See public side of Rails Web app as another domain - ruby-on-rails

Let's say I have a appointment scheduling web app and there are some parts of the Web app that are public for everyone to see, such as Staff or a Request an appointment page. But I want these sections to be visible with the clients domain. How should the domain settings to be adjusted?

There's multiple things you could be saying here. If you have an appointment scheduling app with a public and private aspect of the application, you can use access control in Rails. For example, people in a Staff role are going to fill/manage/view appointments but clients/customers can only request appointments. This is pretty easy and doesn't have anything to do with a (DNS) domain (btw, a domain can mean many things so you need to say DNS domain or security domain or problem domain).
You can use an authentication gem (Devise, Authlogic, Sorcery) to identify users of the systems (they login with a password etc). After someone is identified, they can be authorized (or denied) functionality of the site (with a gem like CanCan). Give your staff users a role called staff. Define staff as being able to manage all Appointments but customers only being able to read and create Appointments.
http://asciicasts.com/episodes/192-authorization-with-cancan
If you are trying to split up the site in this way with DNS domains, that's not a good way to go. But, if you really do have all this authorization and authentication worked out and are asking a DNS question, let's think about this.
You are trying to have /public be www.bizcorp.com and the rest of the app be somethingterrible.heroku.com? That's tricky because the rails app bundles /public and you need a way to split the two based on something. You can do this in rails 3 but you'd be splitting in routes.rb for a given REST resource which is really shared between two domains (appointments). So now my appointments controller can't handle all appointments. I have to route based on a domain name match. So you'd either need to figure out if splitting on domain is really the smart thing to do or you'd need to hack together a PublicAppointments controller and a StaffAppointments controller which is breaking DRY.
There's more here on how to do the routes.rb matching for subdomains and top level domains:
http://asciicasts.com/episodes/221-subdomains-in-rails-3
I'd go the authorization route and put the whole site on the customer's domain. Roles handle the public and private functionality and my URLs don't have to change everywhere. I'd only go with the DNS hackery if I was in a crazy virtual hosted environment or some weird networking constraint.
Hope this gives you some ideas.

Related

OAuth2, SAML, OpenID connect - Which one to use for my scenario?

I work for a company where we give customer (hundreds/thousands of users) access to 2 sites. One owned by a 3rd party SaaS and one owned by us.
Customers spend alot of time registering for both sites and we also spend alot of time removing accounts when customers no longer need access.
I would like users to register for Site A. After successful authentication; a user can click on a link within the site to access Site B but without the user entering credentials.
I want Site A identity to be used to access site B and its resources. I do not need site B resources to be presented on Site A site, but simply allow users to access site B if already authenticated to site A.
Users may have different roles on site B.
What is my best option? Oauth2 sounds like a good option. But will it satisfy my requirement above?
Who will manage the authorisation server? I presume Site B?
Thank you.
Two main options:
OLD TECH WITH COOKIES
Perhaps the cheapest option is to use hosting domains and have 2 apps like this:
mail.google.com
drive.google.com
Use a cookie issued to the parent domain, google.com
Cookie identifies user, to provide a user id
Rights are looked up in each app from the user id
OAUTH2 AND OPENID CONNECT
This is the option for modern apps and they are usually used together, due to being web, mobile and API friendly.
It is a big job though, including user migration, and usually involves giving users a new password. So it needs to be something your company are prepared to invest in.
The Authorization Server (AS) becomes a shared central resource and it is common to use a Cloud Provider to ensure high availability.
RELATED RESOURCES OF MINE
Initial Code Sample with Cloud AS
User Migration Blog Post

Allow users to CNAME to custom subdomain on Heroku App

This may have been answered before (it seems relatively common) but for the life of me I cannot find it, so here we are.
I'm creating a relatively straightforward Ruby on Rails app and am (was?) planning on hosting it on Heroku since I'm already setup there.
The problem I'm having is that I'm creating a landing page builder that needs to allow users to view their website at something like https://their-app.my-app.com. Of course, there will be users who will also want to point their own domains (ex. their-app.com) to that subdomain via a CNAME.
1) Is it possible on Heroku to do that without having to add each one as a custom domain (which of course isn't realistic due to customers being able to add their own).
2) Any recommendations on which service might be the best for hosting this kind of setup? I really love the heroku PaaS setup but of course.. this is a requirement.
Side note: WHen doing it now (Creating a CNAME to point a domain name at the subdomain my app created) I currently get a Heroku page saying "No App Found at this Domain", etc.
Thanks!
Yes, this is doable and automatable on Heroku.
Using the Heroku Platform API, you can programmatically point domains to an app.
Then, your customer will have to point their domain to the value of the cname attribute provided by Heroku.

Cname records for SAAS customers

I'm working on a SAAS product. It's hosted on Windows Azure.
I need to give our customers to option to have CName records.
Our app URL looks like this: login.appname.com
When a customer is created they get their own address created for them that looks like this: login.appname.com/CustomerCompanyName
What I want to do is have our customers URL's look like : login.CustomerCompanyName.com/
What is the best way to go about this.
It's a webapp building in ASP.NET 4/ MVC4 hosted on Microsoft Azure.
Any tips would be greatly appreciated.
Thanks,
Noel
You need to understand the technical limitation with your requirement.
Your application is running at login.appname.com
Customer is created and you provide specific site as login.appname.com/customercompanyname
Note: At this time customercompanyname.com is not even a registered domain or if it is registered it may belong to someone else. (or do you register the customercompanyname.com domain first and then create the new customer in Azure App?
What you want to do is very complex to achieve. It is not impossible however every time you will do that, you will have to modify your Azure app to handle the host header. I personally believe a very ugly work.
So if you want to know what is needed, here is just what I think (others may be different or better solution):
Register a domain name for your customer (customerAcompanyB.com)
Create a custom folder in your Windows Azure Application during development
Modify your your Azure application to handle customerAcompanyB.com hostheader so you can route the request to appname.com/folder_name
In your customerAcompanyB.com domain registrar setup CNAME to route your appname.com

Where should I start in choosing and implementing a ASP.net MVC 3 user/role system?

There is so much information and terms here I find it hard to start think about users. What options would I have for creating a user-based ASP.net MVC 3 web app? I've read of membership, providers, authorization, authentication, session, cookies, roles and profiles, but I can't seem to get a grasp on the big picture of how user-things are handled.
What are the pros/cons of using a built-in microsoft solution here? What is it even called?
Can I use my own database only (I want to work database first)?
In my mind I think like so: I have users and roles in a database. Users have roles. I want to deny access to some actions depending on if the user is logged in and has a specific role. Am I over-simplifying the issue? Where should I start?
At the moment I'm thinking of doing a 100% home brew system like when I was developing using PHP but since there's so much info I feel like that would not be a good approach here.
You want users and roles, i.e. you want to authenticate users and authorize them with privileges using roles. I would highly recommend not rolling your own, as you would in PHP. Instead, I recommend using the .NET "Provider" services -- specifically, the MembershipProvider (for authentication) and the RoleProvider (for authorization).
You can still use the Providers with your own db, they are not exclusive to or exclusive with code first. However, I would recommend NOT storing application-specific user information in the Provider's user or member tables. Instead, you can have your own code-first User, and link it to the membership system through the user's username.
The reason I recommend this is because it reduces the amount of work you have to do. You need not worry about encrypting or hashing passwords -- the provider does it for you. You have full API to control your users and roles through the System.Web.Security namespace.
As for Profiles, this is a separate Provider service that you do not need to use. It allows you to store information about users whether or not they have registered for a user account in your system. Technically you can have "anonymous users", but anyone who has created a password-based login is instead referred to as a "member".
Regarding cookies, authentication of a user in .NET is done through the FormsAuthentication class. After you have authenticated a user using System.Web.Security.Membership, you can call FormsAuthentication.SetAuthCookie to write their authentication cookie. This fully integrates both the User and their Roles into the Controller.User property, which implements the IPrincipal interface. You can use this object to get the user's name, and find out which roles they are in.
Reply to comments
I answered a very similar question here. Basically, it's up to you whether or not to have the membership in a completely separate db than your application, but I consider it good practice, because I have done this quite a bit and I have no complaints. Especially if you are using code first, since you can lose your entire db if you use the DropCreateDatabaseIfModelChanges or DropCreateDatabaseAlways initializers.
There is also a new membership provider. I think the NuGet package is called "ASP.NET Universal Providers", and they are in the System.Web.Providers namespace instead of the old System.Web.Security namespace. I haven't had a chance to work with them yet, but from what I gather, they are more compatible with code first. For one thing, the tables aren't named like aspnet_Foo, and there are no views or stored procedures created in the db. The table names are just normal dbo.Users, dbo.Roles, etc.
As for linking the provider users with your app (content) User entities, see the answer I linked to above. The easiest way to do this is to just have a field in your content db for UserName, and link that to the provider db's UserName. No foreign keys necessary, since you integrate them at the app-level, not the db level.
I think you should first start with built-in solutions, they're easy to extend if someday you'll need something more (even if to write a good providers for authentication isn't really trivial. Start reading this article, it's a good start point).
I don't think to write everything here is a good idea, it's a big topic and I should simplify everything too much so I'll post some links I found useful.
Just to start, with text from MSDN:
Authorization determines whether an identity should be granted access to a specific resource.
Authentication is the process of obtaining identification credentials such as name and password from a user and validating those credentials against some authority.
Imagine users and roles as Windows users and groups. For example a web-site for forums may have a user named AUser with following roles: User, Editor, Moderator. In that web-site they may grant a set of allowed actions: User may enter new posts, Editor may change posts of other people and Moderator may close or delete posts or topics. In this way single web pages don't need to know users but just roles (the DeletePost method of PostController may be decorated with [Authorize(Roles = "Administrator, Moderator")]).
Start reading this very introductory article, it provides additional useful links.

Rails Subdomain Clustering

I am about to be writing a Ruby on Rails app which will use sub-domains to authenticate users. We will have two types of accounts:
user accounts
domain accounts
Users will thus be able to belong to multiple domain accounts using the same credentials. I hope to have the ability for a domain account administrator to be able to search for particular users and add them to their domain.
In addition to simply creating a domain account in the database, I want to setup an actual account on the machine (linux-based) so that users can drop files into a special directory and we can run some scripts to import that new data. Alternatively, I may write a client/server script to make this process easier.
All of this I believe I can do, however, as soon as the project attains a certain number of domain accounts, it will be necessary to figure out how to cluster the domain accounts appropriately so that we can have multiple machines.
From a database standpoint, this is fairly easy and there are lots of tutorials on how to cluster MySQL or whichever SQL server I decide to use. So my question really pertains more to machine accounts as well as how to cluster a Rails app.
If you want a comparison, think of this project like GitHub or Beanstalk but with data that isn't source control related.
Does anybody have any experience with this or know of any really good articles/books to get me started?
Thanks very much!
I suggest you look at using one of the PAM modules that lets you do account authentication against a SQL database. That way you just add the domain account to the SQL database and you get UNIX accounts (on all your servers) automagically, for free. So the clustering should just happen for free too...

Resources