├── config ├── .gitignore ├── dev.php ├── prod.php ├── local.php.dist └── simpleuser_demo.sql ├── var ├── logs │ └── .gitignore └── cache │ └── .gitignore ├── .gitignore ├── web ├── .htaccess ├── index.php └── index_dev.php ├── composer.json ├── README.md ├── phpunit.xml.dist ├── src ├── Demo │ └── User.php └── app.php ├── LICENSE └── templates ├── view.twig ├── index.twig └── layout.twig /config/.gitignore: -------------------------------------------------------------------------------- 1 | local.php -------------------------------------------------------------------------------- /var/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | 4 | -------------------------------------------------------------------------------- /var/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | FallbackResource /index.php 2 | 3 | 4 | php_value newrelic.appname "SimpleUser Demo" 5 | 6 | -------------------------------------------------------------------------------- /config/dev.php: -------------------------------------------------------------------------------- 1 | run(); 10 | -------------------------------------------------------------------------------- /config/local.php.dist: -------------------------------------------------------------------------------- 1 | 'pdo_mysql', 10 | 'dbname' => 'simpleuser_demo', 11 | 'host' => 'localhost', 12 | 'user' => 'simpleuser_demo', 13 | 'password' => '', 14 | ); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Silex SimpleUser Demo 2 | ===================== 3 | 4 | This is an example application to demonstrate [Silex SimpleUser](https://github.com/jasongrimes/silex-simpleuser), 5 | a service provider that implements the missing user management pieces for the Security component. 6 | 7 | See the [online demo](http://silex-simpleuser-demo.grimesit.com). 8 | 9 | For more information, see the [Silex SimpleUser tutorial](http://www.jasongrimes.org/2014/09/simple-user-management-in-silex/). 10 | 11 | -------------------------------------------------------------------------------- /web/index_dev.php: -------------------------------------------------------------------------------- 1 | run(); 22 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 18 | src/tests.php 19 | src/ 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Demo/User.php: -------------------------------------------------------------------------------- 1 | getCustomField('twitterUsername'); 17 | } 18 | 19 | public function setTwitterUsername($twitterUsername) 20 | { 21 | $this->setCustomField('twitterUsername', $twitterUsername); 22 | } 23 | 24 | public function validate() 25 | { 26 | $errors = parent::validate(); 27 | 28 | if ($this->getTwitterUsername() && strpos($this->getTwitterUsername(), '@') !== 0) { 29 | $errors['twitterUsername'] = 'Twitter username must begin with @.'; 30 | } 31 | 32 | return $errors; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jason Grimes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/view.twig: -------------------------------------------------------------------------------- 1 | {% extends layout_template %} 2 | 3 | {% block title %}{{ user.displayName }}{% endblock %} 4 | 5 | {% block content %} 6 | 7 |
8 | 9 | 10 |
11 |

{{ user.displayName }}

12 | 13 | {% if is_granted('EDIT_USER', user) %} 14 |
15 | {{ user.email }} 16 |
17 | {% endif %} 18 | 19 | {# Example of accessing a custom field #} 20 | {% if user.twitterUsername %} 21 |
22 | 23 | {{ user.twitterUsername }} 24 | 25 |
26 | {% endif %} 27 | 28 | {% if is_granted('EDIT_USER', user) %} 29 |
30 | Edit 31 |
32 | {% endif %} 33 |
34 |
35 | 36 | 37 | {% endblock %} 38 | -------------------------------------------------------------------------------- /config/simpleuser_demo.sql: -------------------------------------------------------------------------------- 1 | 2 | -- 3 | -- Use this to reset the demo database periodically, with a crontab like this: 4 | -- 5 | -- 0 * * * * root /usr/bin/mysql --defaults-extra-file={mysql.cnf} {db} < /path/to/silex-simpleuser-demo/config/simpleuser_demo.sql 6 | -- 7 | 8 | TRUNCATE TABLE user_custom_fields; 9 | LOCK TABLES `user_custom_fields` WRITE; 10 | /*!40000 ALTER TABLE `user_custom_fields` DISABLE KEYS */; 11 | INSERT INTO `user_custom_fields` VALUES (1,'twitterUsername','@jason_grimes'),(2,'twitterUsername',''),(3,'twitterUsername',''); 12 | /*!40000 ALTER TABLE `user_custom_fields` ENABLE KEYS */; 13 | UNLOCK TABLES; 14 | 15 | TRUNCATE TABLE users; 16 | LOCK TABLES `users` WRITE; 17 | /*!40000 ALTER TABLE `users` DISABLE KEYS */; 18 | INSERT INTO `users` (id, email, password, salt, roles, name, time_created) 19 | VALUES (1,'jason@grimesit.com','yY2SobUMvwpGMW0tnOCN1r1X/ZG6IrPm2tAn98Y6yU5eY2vbQwXK7cCbj6xH3pAKvo/fUqXPQCWaTPbtBjyHQw==','k94xf6eulyookwooo0ookc4g0o4gcwg','ROLE_USER','Jason Grimes',1410732423),(2,'admin@example.com','GZvr4yFKRLkai8kr9Td1Pzl2B9/00DLDyrQytg49+Gh7ZFz5H88YQL6u/v1JSjjeMlFRLkfo+KJv5E996saaXQ==','dih3xah826o84o80gs088ccwggog8kc','ROLE_ADMIN,ROLE_USER','Ms. Admin',1410914863),(3,'user@example.com','S2pv8CgH0fxRGUFW8/Dc93FXSYTxR5oUmC2qNcsKjt5HPI6IWgdnrvc8u5BPWSPhaazaD6ir5BYeTYeW0LVgRg==','9t57m85zu8848cck0wkookwgg0ccw0c','ROLE_USER','Mr. User',1410960296); 20 | /*!40000 ALTER TABLE `users` ENABLE KEYS */; 21 | UNLOCK TABLES; 22 | -------------------------------------------------------------------------------- /templates/index.twig: -------------------------------------------------------------------------------- 1 | {% extends "layout.twig" %} 2 | 3 | {% block content %} 4 | 5 | {% if app.user %} 6 |
7 |

8 | You are logged in! 9 | Now try this: 10 |

11 | 12 | 18 | 19 | {% if is_granted('ROLE_ADMIN') %} 20 |

21 | Note that as an admin, you can see more information in other users' profiles, 22 | you can edit other users' profiles, 23 | and you can change assigned roles. 24 |

25 | {% endif %} 26 |
27 | {% endif %} 28 | 29 |
30 |

Silex SimpleUser demo

31 | 32 |

33 | This is an example application to demonstrate the 34 | Silex SimpleUser library. 35 |

36 |

37 | See the 38 | source code 39 | or the 40 | tutorial. 41 |

42 |
43 | 44 |

45 | Try signing in with these accounts to experiment: 46 |

47 | 48 | 62 | 63 |

64 | Feel free to create and edit users, but please don't change the email or password of those two accounts. 65 |

66 | 67 |

Demo limitations

68 | 69 | 73 | 74 | {% endblock %} 75 | -------------------------------------------------------------------------------- /src/app.php: -------------------------------------------------------------------------------- 1 | register(new Provider\DoctrineServiceProvider()); 12 | $app->register(new Provider\SecurityServiceProvider()); 13 | $app->register(new Provider\RememberMeServiceProvider()); 14 | $app->register(new Provider\SessionServiceProvider()); 15 | $app->register(new Provider\ServiceControllerServiceProvider()); 16 | $app->register(new Provider\UrlGeneratorServiceProvider()); 17 | $app->register(new Provider\TwigServiceProvider()); 18 | $app->register(new Provider\SwiftmailerServiceProvider()); 19 | 20 | // Register the SimpleUser service provider. 21 | $simpleUserProvider = new SimpleUser\UserServiceProvider(); 22 | $app->register($simpleUserProvider); 23 | 24 | // 25 | // Controllers 26 | // 27 | 28 | $app->mount('/user', $simpleUserProvider); 29 | $app->get('/', function () use ($app) { 30 | return $app['twig']->render('index.twig', array()); 31 | }); 32 | 33 | // 34 | // Configuration 35 | // 36 | // Normally I'd put this stuff in config/prod.php and include it from index.php, 37 | // but for the sake of demonstration it's easier to see it all here in one file. 38 | // 39 | 40 | $app['twig.path'] = array(__DIR__.'/../templates'); 41 | $app['twig.options'] = array('cache' => __DIR__.'/../var/cache/twig'); 42 | 43 | $app['security.firewalls'] = array( 44 | /* 45 | // Ensure that the login page is accessible to all 46 | 'login' => array( 47 | 'pattern' => '^/user/login$', 48 | ),*/ 49 | 'secured_area' => array( 50 | 'pattern' => '^.*$', 51 | 'anonymous' => true, 52 | 'remember_me' => array(), 53 | 'form' => array( 54 | 'login_path' => '/user/login', 55 | 'check_path' => '/user/login_check', 56 | ), 57 | 'logout' => array( 58 | 'logout_path' => '/user/logout', 59 | ), 60 | 'users' => $app->share(function($app) { return $app['user.manager']; }), 61 | ), 62 | ); 63 | 64 | $app['user.options'] = array( 65 | 'templates' => array( 66 | 'layout' => 'layout.twig', 67 | 'view' => 'view.twig', 68 | ), 69 | 'mailer' => array('enabled' => false), 70 | 'editCustomFields' => array('twitterUsername' => 'Twitter username'), 71 | 'userClass' => '\Demo\User', 72 | ); 73 | 74 | // Example of defining a custom password strength validator. 75 | // Must return an error string on failure, or null on success. 76 | $app['user.passwordStrengthValidator'] = $app->protect(function(SimpleUser\User $user, $password) { 77 | if (strlen($password) < 4) { 78 | return 'Password must be at least 4 characters long.'; 79 | } 80 | if (strtolower($password) == strtolower($user->getName())) { 81 | return 'Your password cannot be the same as your name.'; 82 | } 83 | }); 84 | 85 | // Note that this db config is here for example only. 86 | // It actually gets overwritten by configuration in config/local.php, 87 | // which I don't commit to version control. 88 | $app['db.options'] = array( 89 | 'driver' => 'pdo_mysql', 90 | 'host' => 'localhost', 91 | 'dbname' => 'mydbname', 92 | 'user' => 'mydbuser', 93 | 'password' => 'mydbpassword', 94 | ); 95 | 96 | // Local environment configuration that doesn't get committed to version control. 97 | require __DIR__ . '/../config/local.php'; 98 | 99 | return $app; 100 | -------------------------------------------------------------------------------- /templates/layout.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Silex SimpleUser Demo 8 | 9 | 10 | 11 | 12 | 49 | 50 |
51 | {% if app.session.flashbag.has('alert') %} 52 | {% for flashMessage in app.session.flashbag.get('alert') %} 53 |
{{ flashMessage }}
54 | {% endfor %} 55 | {% endif %} 56 | 57 | {% block content %}{% endblock %} 58 |
59 | 60 | 65 | 66 | 67 | 68 | 69 | 70 | 82 | 83 | 84 | 85 | 86 | --------------------------------------------------------------------------------