Storing user documents in S3 - design decisions - amazon-s3

I have an angular web app that will store CVs, cover letters, and user images. I'm trying to come up with a solution of buckets and folders that makes the most sense for my app.
For avatars, which are unique, I think it would be simple to:
have a bucket named avatars
name each avatar with the user-id of the user
For CVs, there are two kinds: one with full contact information, and another one edited to not reveal the contact information. For cover letters, those are also mostly unique. If I store only the most recent version, I could:
have a bucket named Docs
create a folder with the user-id of the user
have items userid/cv-edited.doc, userid/cv-unedited.doc, userid/letter.doc
Is this a reasonable scheme? Are there any pitfalls?

Is there a strong reason to separate the avatars from the user-id folders? It sure seems simpler to keep a single path for all the data... Then you can have permissions driven purely by the path.

Related

How can can i insert a user with profile picture using Blazor-server

I want the user to upload his picture when he registers his information.
The thing is when the user uploads his image.. should automatically create a folder with his ID to be like this wwwroot/images/UserID/fadi.jpg
Basically: you really shouldn't. The wwwroot is for static assets used by the application. You're using server-side, so in theory it might be possible but that's not what the folder is meant for. An alternative method like AWS would be preferred, but if you can't do that (either because of payment requirements or other complications) I would suggest saving the image to your database. One way to do this would be to base64 encode the image and save it that way. I'm not going to give an example of that here, there are plenty available elsewhere. One such example is this.

AMWS s3 bucket image url

I am using AMWS s3 in a ruby on rails project to store images for my models. Everything is working fine. I was just wondering if it okay/normal that if someone right clicks an image, it shows the following url:
https://mybucketname.s3.amazonaws.com/uploads/photo/picture/100/batman.jpg
Is this a hacking risk, letting people see your bucket name? I guess I was expecting to see a bunch of randomized letters or something. /Noob
Yes, it's normal.
It's not a security risk unless your bucket permissions allow unauthenticated actions like uploading and deleting objects by anonymous users (obviously, having the bucket name would be necessary if a malicious user wanted to overwrite your files) or your bucket name itself provides some kind of information you don't want revealed.
If it makes you feel better, you can always associate a CloudFront distribution with your bucket -- a CloudFront distribution has a default hostname like d1a2b3c4dexample.cloudfront.net, which you can use in your links, or you can associate a vanity hostname with the CloudFront distribution, like assets.example.com, neither of which will reveal the bucket name.
But your bucket name, itself, is not considered sensitive information. It is common practice to use links to objects in buckets, which necessarily include the bucket name.

Do I need to create folders in cloudinary?

I am building an new web application and want to use Cloudinary for users' images. My question is that do I need to create folders in my Cloudinary cloud? The reason I am asking is that if I were using a file system and start having 100,000+ images in one folder, it will start killing my app, and I would need to break then into several folders.
Is it the same for Cloudinary?
Thanks,
It depends on your current and future requirements.
In general, I believe that folders can help with better organizing your resources, especially when there are lots of them.
Note that besides folders, you can also assign tags to your images (e.g., by user) or add a prefix to the images' public IDs (e.g., user1-<image_name>).
You can later use Cloudinary's Admin API to list your resources either by folder/prefix or by tag.

Api URI Design Preference

A quick api uri design question. We have resources that belong to our clients. These resources can be edited / viewed / deleted by the client who entered them into our system. The resources can be searched by all clients but access is only granted if certain criteria is met (client has level 3 access etc).
Choice 1: include the client who owns the resource in the uri.
client/:clientname/widgets
client/:clientname/widgets/:id
Choice 2: ditch the whole "client/:clientname" since this part of the uri has to be verified and checked against the credentials of the user accessing the information.
/widgets
/widgets:id
We have other resources other than widgets that also belong to clients.
Which way is the more preferred way and why? Cheers.
The only advantage that Choice 1 gives it that it allows you to effectively namespace widgets/whatever by the user that uploaded them. Similar to Github, how different users can have projects with the same name. If Github were to exclude the username, no two users could have a project with the same name. If the widgets are all unique, I would go with option two and you will have a 1:1 mapping from a widget the the user that created it, thus supplying it is just extra work for whoever is calling it.
If you can have the same widget name for different users, use an approach which includes the username. You may not need to actually use the 'client' word in your url though; using a path like '/:clientname/widget/:widgetid' instead.
Note that this is kind of an opinion based question, so you may get different answers. You'll have to weigh the information provided and in the end make your own decision.

Suggestions on addressing REST resources for API

I'm a new REST convert and I'm trying to design my first RESTful (hopefully) api and here is my question about addressing resources
Some notes first:
The data described here are 3d render
jobs
A user (graphics company) has multiple projects.
A project has multiple render jobs.
A render job has multiple frames.
There is a hierarchy enforced in the data (1 render job
belongs to one project, to one user)
How's this for naming my resourses...?
https:/api.myrenderjobsite.com/
/users/graphicscompany/projects
/users/graphicscompany/projects/112233
/users/graphicscompany/projects/112233/renders/
/users/graphicscompany/projects/112233/renders/889900
/users/graphicscompany/projects/112233/renders/889900/frames/0004
OR a shortened address for renders?
/users/graphicscompany/renders/889900
/users/graphicscompany/renders/889900/frames/0004
OR should I shorten (even more) the address if possible, omitting the user when not needed...?
/projects/112233/
/renders/889900/
/renders/889900/frames/0004
THANK YOU!
Instead of thinking about your api in terms of URLs, try thinking of it more like pages and links
between those pages.
Consider the following:
Will it be reasonable to create a resource for users? Do you have 10, 20 or 50 users? Or do you have 10,000 users? If it is the latter then obviously creating a single resource that represents all users is probably not going too work to well when you do a GET on it.
Is the list of Users a reasonable root url? i.e. The entry point into your service. Should the list of projects that belong to a GraphicsCompany be a separate resource, or should it just be embedded into the Graphics Company resource? You can ask the same question of each of the 1-to-many relationships that exist. Even if you do decide to merge the list of projects into the GraphicsCompany resource, you may still want a distinct resource to exist simple for the purpose of being able to POST to it in order to create a new project for that company.
Using this approach you should be able get a good idea of most of the resources in your API and how they are connected without having to worry about what your URLs look like. In fact if you do the design right, then any client application you right will not need to know anything about the URLs that you create. The only part of the system that cares what the URL looks like is your server, so that it can dispatch the request to the right controller.
The other significant question you need to ask yourself is what media type are you going to use for these resources. How many different clients will need to access these resources? Are you writing the clients, or is someone else? Should you attempt to reuse an existing standard like XHTML and classes/microformats? Could you squeeze most of the information into Atom? Maybe Atom with some extra namespaces like GDATA does it? Or is this only going to be used internally so you can just create your own media types, like application/vnd.YourCompany.Project+xml, application/vnd.YourCompany.Render+xml, etc.
There are many things to think about when designing a REST api, don't get hung up on what your URLs look like and you should really try to avoid doing "design by URL".
Presuming that you authenticate to the service, I would use the 1st option, but remove the user, particularly if the user is the currently logged in user.
If user actually represents something else (like client), I would include it, but not if it simply designates the currently logged in user. Agree with StaxMan, though, don't worry too much about squeezing the paths, as readability is key in RESTful APIs.
Personally I would not try to squeeze path too much, that is, some amount of redundant information is helpful both to quickly see what resource is, and for future expansion.
Generally users won't be typing paths anyway, so verbosity is not all that bad.