I'm developing an application that displays books as interactive flash content with Symfony2. Each book has one index.html file that carries all those flash things embedded in html code and some directories with all required parts of book (images, js files, etc.) linked with this index.html file and each other by 'src' and 'href' tags etc. I'd like to display these books on my website and, at the same time, to prevent anonymous users from downloading them.
For example:
I have my books in web/Books folder and to display Book1 I have to display web/Books/Book1/index.html file. By putting those files in web directory I allow anonymous users to access them by typing for example www.example.com/Books/Book1/index.html or something similar for images, js files etc (paths can be read from content of book's index.html).
Is there any way to prevent from this?
I am an admin of the server, root directory is set on web directory, as recommended.
Thank you in advance for any answers.
EDIT. [SOLVED]
Okay, I found the solution. It's something similar to Pier-Luc's Gendreau proposal.
The idea:
All books are located in 'books' folder, path to index.html of each book is /books/{title}/index.html. In .htaccess I wrote RedirectMatch, for example: /books/book1/index.html is redirected to /bookrouter/book1/index.html. Path like this isn't path to existing file, so Symfony2 can handle it as route. Route pattern is /bookrouter/{path}.{_format} (with requirement for {path} for allowing '/' sign), so I can create accurate response with proper headers and content and serve required files with all required authentication/authorization. There are two bad sides of this:
1. I have to handle each file extension separately to create proper http headers and content.
2. More experienced programmer said that if we will have as many users as we expect, this way of handling each request will kill our server so we can't use it.
So people, thank you for your time! I hope that my solution is described clearly and maybe someone in the future will find it useful. Cheers!
you will need to setup a firewall to deny anonymous users access to certain routes.
See the documentation chapter Security.
For a quick start consider using FOSUserBundle.
Without any modifications to your current structure, I think you're looking for an answer that doesn't exist. The books are outside Symfony, thus ruling out every proper Symfony way of securing access. You're pretty much stuck with basic HTTP authentication with .htaccess.
However, you could bring the books inside Symfony.
Firstly, move your index.html books where the views are stored, renaming every book to it's slug (Book1's index.html becomes Book1.html, etc)
Secondly, create a BookController whose base route is /Books and a secureBookAction with a $slug parameter so that the book route is /Books/{slug}. It seems like you are aware how to secure a route so I'll leave that up to you.
Thirdly, render the view based on the slug parameter. You will probably want to keep a list of the books so you can react properly to a slug that doesn't correspond to a book.
Lastly, I would leave your assets where they are now, just make sure you're using absolute paths otherwise they will break. It'll be simpler that way and they are unlikely to be useful without the accompanying book.
Sorry if my answer is a light on code, I haven't touched anything Symfony in a few weeks though I think I have made the strategy clear.
To secure css, js and image files you should use Assetic, because Assetic generate new URL's for the assets.
For example, here the new URL will be /css/secure :
{% stylesheets '#AcmeFooBundle/Resources/public/css/secure-folder/*' output='css/secure/' filter='cssrewrite' %}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
Then you can restrict this route for anonymous users.
# app/config/security.yml
security:
# ...
access_control:
- { path: ^/css/secure, roles: ROLE_USER }
Related
I'm starting to develop a project that will be quite big (hear lots of files) and I want to have an organization that's different from Symfony's default one: instead of having one dir for all my controllers, another for all my forms, etc, I want to have one dir per functionality, ie a directory for my homepage which will contain the controller, the templates, another dir for the blog page with the controller, forms and templates, and so on.
I tried what was explained in this (old) answer, and it didn't work : my routes weren't recognized, and a php bin/console debug:router showed they weren't listed anymore.
I feel I will have something to adapt in my routes.yaml file, which looks like this for now, and which explains why it doesn't work because it explicitely searches in the src\Controller directory:
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute
I looked in the documentation I found, but I didn't find anything useful (I think I will have to remove the path and change it to something else, but I don't know what yet.
The above solutions are only for differentiating controller and template files. But For Entity, Events, and Forms it will not work.
It seems like you want to separate files for each module or functionality. For example, settings.yaml, controller, entity, forms, events, etc...
For that Symfony provides a Bundle feature. You can create a new Bundle in Symfony and use it as a separate feature. For more details please read this link
I am looking for any reference material for me to read up on, relating to what enables the following scenario where a website has a unique identifer appended to their domain name.
When you go to Facebook and view your profile, the URL in the address bar is something lile;
https://www.facebook.com/your_user_name.number
There is no obvious file extension, nor is the 'your_user_name.number' being passed as querystring value. I do know that I could create a folder on the web directory which is this name, and then you can direct to that folder and it will autoload the default or index files based on your web server settings. But i am not sure this is happening in this case, as then Facebook would have to create 2 billion + folders?
Browsing to your Photos on Facebook, it the url then looks like;
https://www.facebook.com/your_user_name.number/photos
I am keen to understand what this type of technical configuration is called. Happy to read up on it myself and learn about it, but I don't even know what it's called to search and read up on.
Any pointers?
What you are looking for is URL rewrite.
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/creating-rewrite-rules-for-the-url-rewrite-module
You can basically do whatever you want! No need for extensions or folders at all if you don’t want them anywhere.
Let's say I have created a news portal bundle "NewsBundle" with articles, tags, events, lots of relations, quite huge and complex.
Now I want to copy this numerous times and create a Fashion News Portal, Car News Portal, Dog News portal and so on each available though an own domain. The portals differ only in templates, translations and assets. As I want to implement complex reporting, I want all the stuff in a single database and would flag all entities with the respective portal.
My question: How so I organize the code?
First I figured out, I could use routing to have the same application but different bundles for each domain.
Then I found out, that I could extend my master bundle. But it seems as this works only once.
As I did all the routing with annotations, it look like it does not work to inherit the routes from the master?
One of the hardest questions is where to put the portal switch. Somewhere I need to set a variable that tells whether its the fashion or dogs portal, so I can filter the content in all repositories accordingly.
I did that in the app.php which is for sure worst practise.
In the end I want to be able to roll out new portals easily without duplicate code.
Any ideas are much appreciated.
Greetings from Hamburg,
Boris
You need to keep your NewsBundle in your application, and to have a number of bundles revolving around it, one for each portal you intend to create.
There is no real need for bundle inheritance here. Your portal bundles depends on the NewsBundle but don't inherit from it.
Routing configuration, templating, and other behaviours related to a specific portal should go in the related bundle. There is a Resources folder in each bundle ; this is where you will need to put specific routing, translation, configuration and templates.
app/config/routing.yml is the central routing conf file where you will need to reference all other routing.yml file.
As for the switch, well, I can't answer that in detail but I think it should be set up in your server application apache or nginx (or other...).
Your problem can be solved via different environments. Each of your portal is a different environment. You can set up your web server to point different front-controllers depending on the domain requested.
Example:
For domain news.domain.com your front-controller would be web/app_news.php. And it will contain line:
$kernel = new AppKernel('news', false);
It will automatically load config from app/config/config_news.yml. In that config you can specify all specific parameters for your portal. You need then just implement your special loader for resources like translations that will load resources from the path specified in config_news.yml.
I have regrouped the following information from a few examples in the SonataAdminBundle documentation. Please correct me if there are some errors, but here is what I get in the case of a BlogBundle:
As you can see, in general, each bundle contains both frontend and backend classes.
It seems very messy to mix both frontend and backend in the same folders somtetimes (see Controllers), but to be honest I can't think of an other way...
I actually started handling backend in a separate bundle but then realised that it was also too messy.
So in practice, do people really follow this architecture? Is this the only/best way to handle backend when using SonataAdminBundle?
This beautiful post here is using a different approach...any ideas what I should do to make sure the code doesn't get too messy.
Simple: use folders within locations of mixed content. I put frontend components directly in their respective folders, and add Admin folders for backend files.
You can refer to e.g. a controller in the Admin subfolder like this BlogBundle:Admin\Concert:index, essentially the same works for templates.
On configuration, you could create a config-frontend.yml and a config-backend.yml file, then include it in the original config.yml file. I don't do that though.
alias:
admin/a/b
source:
sites/all/modules/somemodule/somefile
I tried in menu, pathauto, they both report such source path does not exist or I don't have permission. How can this be achieved in most easy way?
Url alias doesn't work with files, only paths that are known by Drupal (defined in the code/database).
Update:
Path aliases work by rewriting the url into something that Drupal understands. So if you wanted to make an alias to a file, you would need to serve the file yourself, since Drupal doesn't serve the files.
If you really wanted to, you could make a redirect to the file from, but that's not pretty.
Try setting the Download Method to private, under admin/settings/file-system. If you do, Drupal will serve your files and the redirects might work (I didn't test it myself... :-).
Naturally, this has a price in terms of performance. Your links will look different.
If you want to keep the public download method, your need to redirect in the HTTP server level, because file requests are not going through Drupal in that case.