[MUSIC] Welcome back. In this section, we're going to finish up the last five topics of the core application architecture areas which deal with security, image handling, geocode and geolocation queries, maps and communications. That fills out the lower potion of the core application stack. Now remember, the purpose of going through this is not to teach you specifically these topics. It's just to give you a picture of the overall scope of the application we're going to be dealing with in the capstone. One of the main purposes of the capstone is to do something useful with the different technologies you've been learning in the other courses. And what useful application wouldn't involve some form of authenticated access to the application? Whereas we might need to establish accounts, we might need to login, logout, and we might need some role specific authorizations. For example, in our application, it's an information collaboration with images and things. If I post an image, who's allowed to edit or delete that image? If I am managing a thing, who's allowed to see the details of the thing that I am posting? On the server side, we're going to be making use of the Devise gem. The Devise gem is a very mature and commonly used solution for account management and core authentication. And Devise has countless other extensions, which can make it a very complicated gem to research and fully understand. However, keeping it at its core account management and core authentication capabilities is rather trivial, or rather simple and straight forward. And if we're able to insert this very popular gem in the middle of our application, we will open ourselves to countless amounts of authentication schemes throughout the Internet. Devise does support ActiveRecord. It also supports Mongoid. However, another gem that we'll be adding on top in order to help support web services, the devise-token-auth gem, does not, though our choice was reduced back to just doing ActiveRecord and putting our credentials in the relational database. Meeting in the middle and implementing our web services authentication is the devise-token-auth gem and the ng-token-auth module that is provided by the same developer. The devise-token-auth gem interfaces with Devise and the user store in the active record in order to implement the web service bearer token protocol. In the web service bearer token protocol, the client is going to authenticate and the gem is going to generate a token which needs to be supplied on the next request. That token or some tracking of that token is going to be stored into the active record database. On the client side, the ng-token-auth is taking care of authentication with a user password prompt and then remembering the bearer taken and listening to the htp protocol going on between the client and the server within Angular. And sucking off the token and putting it on to the next request in keeping track of the token switchovers. The module also takes advantage of the browser cookie store. And will store whatever it needs in order to recover from a browser refresh or if we log out of our machine and log back in the next day to be able to start out with the next bearer token that's involved. Now if the bearer token expires, then we're right back in a login authentication. If we come back soon enough, we're able to pick up where we left off. For authorization, there is no end-to-end solution, but where we can start is with the Pundit Authorization Gem. This a lightweight framework that allows us to isolate authorization decisions from business logic, keeping the two from being intertwined with one one another. And then in support of the client we can do something like server-side redaction, making sure that information the user has no access to they don't get it. We also can do server-side marking and say, the user who asked for this information has the following roles relative to this information. Then on the client side, what we can do is use standard directives like ng-f, ng-show, ng-hide. And be able to add or remove certain buttons from the user's ability. If the client were to make those requests, the server would simply say, you're not authorized to do those kinds of things. But on the client side, we don't want the client to get that far. So we will use those markings and these conditional content directives in order to provide them the correct user experience relative to that information. One of the main emphasis of the capstone is photo sharing. And let's face it, photo sharing is fun. We like to share photos of our trips that we're going on, and we'd like to do that within our application. However, obviously, if we're going to share photos within our application, we're going to have to address image handling. And one of the first use cases that we're going to have to solve with image handling is where we get our photos from. And we bring in a particular module, and on the Angular side, an ng-file upload, which through a simple input tag and some extra configuration are going to be able to read the photo directly from the camera or from a file system, if that's where the source is. Now one of the problems we have to solve with getting all these collaborative photos is consistency. And so what we need to do is insert a module that will give us the ability to crop these images to a consistent aspect ratio. And we bring in ngImgCropFullExtended. ngImgCropFullExtended does integrate directly with ng-file-upload. And it's a fork of the ng-img-crop module that's also available on the Internet. And you'll see a lot of documentation that speaks in terms of ng-file-upload and ng-img-crop. However, you'll also notice that ng-img-crop hasn't been updated in over two years. And most of the updates to that library have been carried forward recently into the image crop full extent fork. And so that's what we'll be using. We're going to restrict our applications to jpg images, and when the client posts the jpg image to the server, there's a number of things that have to be done. And one of the first things that has to be done is to determine the dimensions of the incoming image. And what we're going to do is take advantage of the EXIF information that's available inside of a JPEG that has that simple information and use the EXIF reader gem in order to pull that out. Now when we work with images, we're going to want to work with images of different sizes. There are times where we're going to want full size images, and there are other times where we're just going to want thumbnails for lists. And so when we get our original in, we're going to want to turn around and create a standard set of sizes that our clients know that they can extract. In order to create those sizes, what we're going to do is take advantage of a negative image manipulation software called ImageMagic. We're going to install that locally and hand it jobs to do, and it's going to give us back the images to work with. In order to interface with that, there were a number of choices. MiniMagic is probably the most simplistic, and that's really all we need, which we need to resize our images. So it's a gem that basically gives us a shell interface to this native application that we're going to install locally. And at the end of this use case, when the image is posted to the server, we should have one file, the original image, as well as about three to five different sizes that clients can request based on size. So what good is a picture of a place or a thing if you don't know where it is? Is it a mile from us? Is it 50 miles, 1,000 miles, or the other side of the Earth? So what we would like to do is add some geocode information so we can give the user perspective of where these things are. When we speak of geolocation, we're primarily talking about marking objects with latitude and longitude information. Now our business objects are in ActiveRecord relational database, so that's where we're going to need to place them. If you remember in course three we added latitude and longitude information to the Mongo database, and used Mongo's built-in geolocation capabilities. But we're not going to have access to that if we put them in the relational side. So what we're going to do is on top of the relational database in ActiveRecord, we're going to add a gem called Geokit Rails, which gives us geolocation queries that gives us the same effect. How far is it from an origin? Order things based upon distance and good capabilities like that for the relational database side. Okay, now that we have a place to store the lat and long for business objects in the relational database, we need to be able to get that information from some source. Enter the Geokit gem, which is going to help us query Geocode providers where what we're going to do is supply them a lat and long, where we're going to supply them a partial street address. And they're going to be able to give us full location information back, and which we can store or keep around what we want. And the provider we're going to use is the Google Maps Geocode Service. This is a free service below 2,500 requests per day. All we need to do is sign up for a free API key, and bake that into our application. Now one of the things that Google does recommend is that you put some kind of persistent cache on your side, which we will do, that as you ask Google questions and you get a response back, you should cache that for a period of time so that you don't exceed your limits. So what we're going to do is we're going to take Mongoid and MongoDB. And we're going to key it up by latitude, longitude, and a normalized address. And remember, the answer's coming back from Google so that we can stay within license constraints. In order to give our users the best perspective of the photos and the things they're about, we would like to show their position on a map. Our map is going to be able to show them images and information about our tourism area. To implement the maps is conceptually straightforward. We're going to integrate the Google Maps JavaScript API into our Angular application and then we're going to obtain the Geocode information with the lat and long in business data from our API, and ask the library to display that onto the map. Now the Google Maps Service is free for under 2,500 page reloads a day, which is well within the bounds of what we'll need for our application. And when we finish, we'll have something pretty cool and pretty useful for you to continue to play with. To round out the core application, we're going to be finally talking about communications. And in order to have some simplicity about our application, we're going to restrict things to just JSON. And on the server side, what we have as our core implementation or our logical framework is the Rails Controller, which supplies RESTful interface to our resources. We explored that in great detail in course three, as well as some other implementation details in course two. Hidden behind the scene is Rails ActionPack, which handles communications from request to response and all the layers that it has to go through. We don't really see all that going on, but our successful communication relies on it. For JSON marshalling, we're going to take advantage of the same implementations that we used in courses two and three to keep some consistency. It is a DSL paste in the view of the model view controller and it forms the marshall output that the client is going to consume. As I said, it's one of many different JSON marshalling options. There are others that are more language-based that can be more performant and have more features to them. This is more document-based that allows us to describe the information in more document form. On the client side, we're going to take advantage of a module called ngResource, which provides a RESTful client to the resource and access like the peer to the rails controller. It's implemented on top of the HTTP servers that you used quite a bit in course five. However, it has more RESTful kinds of semantics to it, and how things are done. Now under the covers, when you do actually have to change the payloads and do some manipulation, we will rely on Angular built-in JSON marshalling, in order to hand JSON back over to ngResource, in order to complete that overall protocol stack. We have finished going through the remaining five of the seven core application areas, which those being security, having authentication and authorization, image handling, handling everything from a file upload to resizing and storage. Geocode and geolocation queries and getting information from the Google maps Geocode API, mapping, and integrating in all of our geolocation information and business information in with Google Maps and communication in order to exchange JSON information to and from the server. What we're going to go to next is to finish up the technical architecture and talk more about development through deployment.