image_authentication 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +19 -0
- data/README.md +43 -0
- data/app/.DS_Store +0 -0
- data/app/assets/.DS_Store +0 -0
- data/app/assets/images/.DS_Store +0 -0
- data/app/assets/images/image_authentication/.DS_Store +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/1.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/10.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/11.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/12.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/13.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/14.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/15.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/16.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/17.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/18.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/19.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/2.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/20.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/3.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/4.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/5.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/6.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/7.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/8.png +0 -0
- data/app/assets/images/image_authentication/Aeroplanes/9.png +0 -0
- data/app/assets/images/image_authentication/Beverages/1.png +0 -0
- data/app/assets/images/image_authentication/Beverages/10.png +0 -0
- data/app/assets/images/image_authentication/Beverages/11.png +0 -0
- data/app/assets/images/image_authentication/Beverages/12.png +0 -0
- data/app/assets/images/image_authentication/Beverages/13.png +0 -0
- data/app/assets/images/image_authentication/Beverages/14.png +0 -0
- data/app/assets/images/image_authentication/Beverages/15.png +0 -0
- data/app/assets/images/image_authentication/Beverages/16.png +0 -0
- data/app/assets/images/image_authentication/Beverages/17.png +0 -0
- data/app/assets/images/image_authentication/Beverages/18.png +0 -0
- data/app/assets/images/image_authentication/Beverages/19.png +0 -0
- data/app/assets/images/image_authentication/Beverages/2.png +0 -0
- data/app/assets/images/image_authentication/Beverages/20.png +0 -0
- data/app/assets/images/image_authentication/Beverages/3.png +0 -0
- data/app/assets/images/image_authentication/Beverages/4.png +0 -0
- data/app/assets/images/image_authentication/Beverages/5.png +0 -0
- data/app/assets/images/image_authentication/Beverages/6.png +0 -0
- data/app/assets/images/image_authentication/Beverages/7.png +0 -0
- data/app/assets/images/image_authentication/Beverages/8.png +0 -0
- data/app/assets/images/image_authentication/Beverages/9.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/1.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/10.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/11.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/12.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/13.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/14.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/15.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/16.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/17.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/18.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/19.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/2.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/20.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/3.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/4.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/5.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/6.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/7.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/8.png +0 -0
- data/app/assets/images/image_authentication/Bicycles/9.png +0 -0
- data/app/assets/images/image_authentication/Birds/1.png +0 -0
- data/app/assets/images/image_authentication/Birds/10.png +0 -0
- data/app/assets/images/image_authentication/Birds/11.png +0 -0
- data/app/assets/images/image_authentication/Birds/12.png +0 -0
- data/app/assets/images/image_authentication/Birds/13.png +0 -0
- data/app/assets/images/image_authentication/Birds/14.png +0 -0
- data/app/assets/images/image_authentication/Birds/15.png +0 -0
- data/app/assets/images/image_authentication/Birds/16.png +0 -0
- data/app/assets/images/image_authentication/Birds/17.png +0 -0
- data/app/assets/images/image_authentication/Birds/18.png +0 -0
- data/app/assets/images/image_authentication/Birds/19.png +0 -0
- data/app/assets/images/image_authentication/Birds/2.png +0 -0
- data/app/assets/images/image_authentication/Birds/20.png +0 -0
- data/app/assets/images/image_authentication/Birds/3.png +0 -0
- data/app/assets/images/image_authentication/Birds/4.png +0 -0
- data/app/assets/images/image_authentication/Birds/5.png +0 -0
- data/app/assets/images/image_authentication/Birds/6.png +0 -0
- data/app/assets/images/image_authentication/Birds/7.png +0 -0
- data/app/assets/images/image_authentication/Birds/8.png +0 -0
- data/app/assets/images/image_authentication/Birds/9.png +0 -0
- data/app/assets/images/image_authentication/Boats/1.png +0 -0
- data/app/assets/images/image_authentication/Boats/10.png +0 -0
- data/app/assets/images/image_authentication/Boats/11.png +0 -0
- data/app/assets/images/image_authentication/Boats/12.png +0 -0
- data/app/assets/images/image_authentication/Boats/13.png +0 -0
- data/app/assets/images/image_authentication/Boats/14.png +0 -0
- data/app/assets/images/image_authentication/Boats/15.png +0 -0
- data/app/assets/images/image_authentication/Boats/16.png +0 -0
- data/app/assets/images/image_authentication/Boats/17.png +0 -0
- data/app/assets/images/image_authentication/Boats/18.png +0 -0
- data/app/assets/images/image_authentication/Boats/19.png +0 -0
- data/app/assets/images/image_authentication/Boats/2.png +0 -0
- data/app/assets/images/image_authentication/Boats/20.png +0 -0
- data/app/assets/images/image_authentication/Boats/3.png +0 -0
- data/app/assets/images/image_authentication/Boats/4.png +0 -0
- data/app/assets/images/image_authentication/Boats/5.png +0 -0
- data/app/assets/images/image_authentication/Boats/6.png +0 -0
- data/app/assets/images/image_authentication/Boats/7.png +0 -0
- data/app/assets/images/image_authentication/Boats/8.png +0 -0
- data/app/assets/images/image_authentication/Boats/9.png +0 -0
- data/app/assets/images/image_authentication/Cars/1.png +0 -0
- data/app/assets/images/image_authentication/Cars/10.png +0 -0
- data/app/assets/images/image_authentication/Cars/11.png +0 -0
- data/app/assets/images/image_authentication/Cars/12.png +0 -0
- data/app/assets/images/image_authentication/Cars/13.png +0 -0
- data/app/assets/images/image_authentication/Cars/14.png +0 -0
- data/app/assets/images/image_authentication/Cars/15.png +0 -0
- data/app/assets/images/image_authentication/Cars/16.png +0 -0
- data/app/assets/images/image_authentication/Cars/17.png +0 -0
- data/app/assets/images/image_authentication/Cars/18.png +0 -0
- data/app/assets/images/image_authentication/Cars/19.png +0 -0
- data/app/assets/images/image_authentication/Cars/2.png +0 -0
- data/app/assets/images/image_authentication/Cars/20.png +0 -0
- data/app/assets/images/image_authentication/Cars/3.png +0 -0
- data/app/assets/images/image_authentication/Cars/4.png +0 -0
- data/app/assets/images/image_authentication/Cars/5.png +0 -0
- data/app/assets/images/image_authentication/Cars/6.png +0 -0
- data/app/assets/images/image_authentication/Cars/7.png +0 -0
- data/app/assets/images/image_authentication/Cars/8.png +0 -0
- data/app/assets/images/image_authentication/Cars/9.png +0 -0
- data/app/assets/images/image_authentication/Cats/1.png +0 -0
- data/app/assets/images/image_authentication/Cats/10.png +0 -0
- data/app/assets/images/image_authentication/Cats/11.png +0 -0
- data/app/assets/images/image_authentication/Cats/12.png +0 -0
- data/app/assets/images/image_authentication/Cats/13.png +0 -0
- data/app/assets/images/image_authentication/Cats/14.png +0 -0
- data/app/assets/images/image_authentication/Cats/15.png +0 -0
- data/app/assets/images/image_authentication/Cats/16.png +0 -0
- data/app/assets/images/image_authentication/Cats/17.png +0 -0
- data/app/assets/images/image_authentication/Cats/18.png +0 -0
- data/app/assets/images/image_authentication/Cats/19.png +0 -0
- data/app/assets/images/image_authentication/Cats/2.png +0 -0
- data/app/assets/images/image_authentication/Cats/20.png +0 -0
- data/app/assets/images/image_authentication/Cats/3.png +0 -0
- data/app/assets/images/image_authentication/Cats/4.png +0 -0
- data/app/assets/images/image_authentication/Cats/5.png +0 -0
- data/app/assets/images/image_authentication/Cats/6.png +0 -0
- data/app/assets/images/image_authentication/Cats/7.png +0 -0
- data/app/assets/images/image_authentication/Cats/8.png +0 -0
- data/app/assets/images/image_authentication/Cats/9.png +0 -0
- data/app/assets/images/image_authentication/Clocks/1.png +0 -0
- data/app/assets/images/image_authentication/Clocks/10.png +0 -0
- data/app/assets/images/image_authentication/Clocks/11.png +0 -0
- data/app/assets/images/image_authentication/Clocks/12.png +0 -0
- data/app/assets/images/image_authentication/Clocks/13.png +0 -0
- data/app/assets/images/image_authentication/Clocks/14.png +0 -0
- data/app/assets/images/image_authentication/Clocks/15.png +0 -0
- data/app/assets/images/image_authentication/Clocks/16.png +0 -0
- data/app/assets/images/image_authentication/Clocks/17.png +0 -0
- data/app/assets/images/image_authentication/Clocks/18.png +0 -0
- data/app/assets/images/image_authentication/Clocks/19.png +0 -0
- data/app/assets/images/image_authentication/Clocks/2.png +0 -0
- data/app/assets/images/image_authentication/Clocks/20.png +0 -0
- data/app/assets/images/image_authentication/Clocks/3.png +0 -0
- data/app/assets/images/image_authentication/Clocks/4.png +0 -0
- data/app/assets/images/image_authentication/Clocks/5.png +0 -0
- data/app/assets/images/image_authentication/Clocks/6.png +0 -0
- data/app/assets/images/image_authentication/Clocks/7.png +0 -0
- data/app/assets/images/image_authentication/Clocks/8.png +0 -0
- data/app/assets/images/image_authentication/Clocks/9.png +0 -0
- data/app/assets/images/image_authentication/Dogs/1.png +0 -0
- data/app/assets/images/image_authentication/Dogs/10.png +0 -0
- data/app/assets/images/image_authentication/Dogs/11.png +0 -0
- data/app/assets/images/image_authentication/Dogs/12.png +0 -0
- data/app/assets/images/image_authentication/Dogs/13.png +0 -0
- data/app/assets/images/image_authentication/Dogs/14.png +0 -0
- data/app/assets/images/image_authentication/Dogs/15.png +0 -0
- data/app/assets/images/image_authentication/Dogs/16.png +0 -0
- data/app/assets/images/image_authentication/Dogs/17.png +0 -0
- data/app/assets/images/image_authentication/Dogs/18.png +0 -0
- data/app/assets/images/image_authentication/Dogs/19.png +0 -0
- data/app/assets/images/image_authentication/Dogs/2.png +0 -0
- data/app/assets/images/image_authentication/Dogs/20.png +0 -0
- data/app/assets/images/image_authentication/Dogs/3.png +0 -0
- data/app/assets/images/image_authentication/Dogs/4.png +0 -0
- data/app/assets/images/image_authentication/Dogs/5.png +0 -0
- data/app/assets/images/image_authentication/Dogs/6.png +0 -0
- data/app/assets/images/image_authentication/Dogs/7.png +0 -0
- data/app/assets/images/image_authentication/Dogs/8.png +0 -0
- data/app/assets/images/image_authentication/Dogs/9.png +0 -0
- data/app/assets/images/image_authentication/Fish/1.png +0 -0
- data/app/assets/images/image_authentication/Fish/10.png +0 -0
- data/app/assets/images/image_authentication/Fish/11.png +0 -0
- data/app/assets/images/image_authentication/Fish/12.png +0 -0
- data/app/assets/images/image_authentication/Fish/13.png +0 -0
- data/app/assets/images/image_authentication/Fish/14.png +0 -0
- data/app/assets/images/image_authentication/Fish/15.png +0 -0
- data/app/assets/images/image_authentication/Fish/16.png +0 -0
- data/app/assets/images/image_authentication/Fish/17.png +0 -0
- data/app/assets/images/image_authentication/Fish/18.png +0 -0
- data/app/assets/images/image_authentication/Fish/19.png +0 -0
- data/app/assets/images/image_authentication/Fish/2.png +0 -0
- data/app/assets/images/image_authentication/Fish/20.png +0 -0
- data/app/assets/images/image_authentication/Fish/3.png +0 -0
- data/app/assets/images/image_authentication/Fish/4.png +0 -0
- data/app/assets/images/image_authentication/Fish/5.png +0 -0
- data/app/assets/images/image_authentication/Fish/6.png +0 -0
- data/app/assets/images/image_authentication/Fish/7.png +0 -0
- data/app/assets/images/image_authentication/Fish/8.png +0 -0
- data/app/assets/images/image_authentication/Fish/9.png +0 -0
- data/app/assets/images/image_authentication/Flowers/1.png +0 -0
- data/app/assets/images/image_authentication/Flowers/10.png +0 -0
- data/app/assets/images/image_authentication/Flowers/11.png +0 -0
- data/app/assets/images/image_authentication/Flowers/12.png +0 -0
- data/app/assets/images/image_authentication/Flowers/13.png +0 -0
- data/app/assets/images/image_authentication/Flowers/14.png +0 -0
- data/app/assets/images/image_authentication/Flowers/15.png +0 -0
- data/app/assets/images/image_authentication/Flowers/16.png +0 -0
- data/app/assets/images/image_authentication/Flowers/17.png +0 -0
- data/app/assets/images/image_authentication/Flowers/18.png +0 -0
- data/app/assets/images/image_authentication/Flowers/19.png +0 -0
- data/app/assets/images/image_authentication/Flowers/2.png +0 -0
- data/app/assets/images/image_authentication/Flowers/20.png +0 -0
- data/app/assets/images/image_authentication/Flowers/3.png +0 -0
- data/app/assets/images/image_authentication/Flowers/4.png +0 -0
- data/app/assets/images/image_authentication/Flowers/5.png +0 -0
- data/app/assets/images/image_authentication/Flowers/6.png +0 -0
- data/app/assets/images/image_authentication/Flowers/7.png +0 -0
- data/app/assets/images/image_authentication/Flowers/8.png +0 -0
- data/app/assets/images/image_authentication/Flowers/9.png +0 -0
- data/app/assets/images/image_authentication/Food/1.png +0 -0
- data/app/assets/images/image_authentication/Food/10.png +0 -0
- data/app/assets/images/image_authentication/Food/11.png +0 -0
- data/app/assets/images/image_authentication/Food/12.png +0 -0
- data/app/assets/images/image_authentication/Food/13.png +0 -0
- data/app/assets/images/image_authentication/Food/14.png +0 -0
- data/app/assets/images/image_authentication/Food/15.png +0 -0
- data/app/assets/images/image_authentication/Food/16.png +0 -0
- data/app/assets/images/image_authentication/Food/17.png +0 -0
- data/app/assets/images/image_authentication/Food/18.png +0 -0
- data/app/assets/images/image_authentication/Food/19.png +0 -0
- data/app/assets/images/image_authentication/Food/2.png +0 -0
- data/app/assets/images/image_authentication/Food/20.png +0 -0
- data/app/assets/images/image_authentication/Food/3.png +0 -0
- data/app/assets/images/image_authentication/Food/4.png +0 -0
- data/app/assets/images/image_authentication/Food/5.png +0 -0
- data/app/assets/images/image_authentication/Food/6.png +0 -0
- data/app/assets/images/image_authentication/Food/7.png +0 -0
- data/app/assets/images/image_authentication/Food/8.png +0 -0
- data/app/assets/images/image_authentication/Food/9.png +0 -0
- data/app/assets/images/image_authentication/Furniture/1.png +0 -0
- data/app/assets/images/image_authentication/Furniture/10.png +0 -0
- data/app/assets/images/image_authentication/Furniture/11.png +0 -0
- data/app/assets/images/image_authentication/Furniture/12.png +0 -0
- data/app/assets/images/image_authentication/Furniture/13.png +0 -0
- data/app/assets/images/image_authentication/Furniture/14.png +0 -0
- data/app/assets/images/image_authentication/Furniture/15.png +0 -0
- data/app/assets/images/image_authentication/Furniture/16.png +0 -0
- data/app/assets/images/image_authentication/Furniture/17.png +0 -0
- data/app/assets/images/image_authentication/Furniture/18.png +0 -0
- data/app/assets/images/image_authentication/Furniture/19.png +0 -0
- data/app/assets/images/image_authentication/Furniture/2.png +0 -0
- data/app/assets/images/image_authentication/Furniture/20.png +0 -0
- data/app/assets/images/image_authentication/Furniture/3.png +0 -0
- data/app/assets/images/image_authentication/Furniture/4.png +0 -0
- data/app/assets/images/image_authentication/Furniture/5.png +0 -0
- data/app/assets/images/image_authentication/Furniture/6.png +0 -0
- data/app/assets/images/image_authentication/Furniture/7.png +0 -0
- data/app/assets/images/image_authentication/Furniture/8.png +0 -0
- data/app/assets/images/image_authentication/Furniture/9.png +0 -0
- data/app/assets/images/image_authentication/Houses/1.png +0 -0
- data/app/assets/images/image_authentication/Houses/10.png +0 -0
- data/app/assets/images/image_authentication/Houses/11.png +0 -0
- data/app/assets/images/image_authentication/Houses/12.png +0 -0
- data/app/assets/images/image_authentication/Houses/13.png +0 -0
- data/app/assets/images/image_authentication/Houses/14.png +0 -0
- data/app/assets/images/image_authentication/Houses/15.png +0 -0
- data/app/assets/images/image_authentication/Houses/16.png +0 -0
- data/app/assets/images/image_authentication/Houses/17.png +0 -0
- data/app/assets/images/image_authentication/Houses/18.png +0 -0
- data/app/assets/images/image_authentication/Houses/19.png +0 -0
- data/app/assets/images/image_authentication/Houses/2.png +0 -0
- data/app/assets/images/image_authentication/Houses/20.png +0 -0
- data/app/assets/images/image_authentication/Houses/3.png +0 -0
- data/app/assets/images/image_authentication/Houses/4.png +0 -0
- data/app/assets/images/image_authentication/Houses/5.png +0 -0
- data/app/assets/images/image_authentication/Houses/6.png +0 -0
- data/app/assets/images/image_authentication/Houses/7.png +0 -0
- data/app/assets/images/image_authentication/Houses/8.png +0 -0
- data/app/assets/images/image_authentication/Houses/9.png +0 -0
- data/app/assets/images/image_authentication/Insects/1.png +0 -0
- data/app/assets/images/image_authentication/Insects/10.png +0 -0
- data/app/assets/images/image_authentication/Insects/11.png +0 -0
- data/app/assets/images/image_authentication/Insects/12.png +0 -0
- data/app/assets/images/image_authentication/Insects/13.png +0 -0
- data/app/assets/images/image_authentication/Insects/14.png +0 -0
- data/app/assets/images/image_authentication/Insects/15.png +0 -0
- data/app/assets/images/image_authentication/Insects/16.png +0 -0
- data/app/assets/images/image_authentication/Insects/17.png +0 -0
- data/app/assets/images/image_authentication/Insects/18.png +0 -0
- data/app/assets/images/image_authentication/Insects/19.png +0 -0
- data/app/assets/images/image_authentication/Insects/2.png +0 -0
- data/app/assets/images/image_authentication/Insects/20.png +0 -0
- data/app/assets/images/image_authentication/Insects/3.png +0 -0
- data/app/assets/images/image_authentication/Insects/4.png +0 -0
- data/app/assets/images/image_authentication/Insects/5.png +0 -0
- data/app/assets/images/image_authentication/Insects/6.png +0 -0
- data/app/assets/images/image_authentication/Insects/7.png +0 -0
- data/app/assets/images/image_authentication/Insects/8.png +0 -0
- data/app/assets/images/image_authentication/Insects/9.png +0 -0
- data/app/assets/images/image_authentication/Money/1.png +0 -0
- data/app/assets/images/image_authentication/Money/10.png +0 -0
- data/app/assets/images/image_authentication/Money/11.png +0 -0
- data/app/assets/images/image_authentication/Money/12.png +0 -0
- data/app/assets/images/image_authentication/Money/13.png +0 -0
- data/app/assets/images/image_authentication/Money/14.png +0 -0
- data/app/assets/images/image_authentication/Money/15.png +0 -0
- data/app/assets/images/image_authentication/Money/16.png +0 -0
- data/app/assets/images/image_authentication/Money/17.png +0 -0
- data/app/assets/images/image_authentication/Money/18.png +0 -0
- data/app/assets/images/image_authentication/Money/19.png +0 -0
- data/app/assets/images/image_authentication/Money/2.png +0 -0
- data/app/assets/images/image_authentication/Money/20.png +0 -0
- data/app/assets/images/image_authentication/Money/3.png +0 -0
- data/app/assets/images/image_authentication/Money/4.png +0 -0
- data/app/assets/images/image_authentication/Money/5.png +0 -0
- data/app/assets/images/image_authentication/Money/6.png +0 -0
- data/app/assets/images/image_authentication/Money/7.png +0 -0
- data/app/assets/images/image_authentication/Money/8.png +0 -0
- data/app/assets/images/image_authentication/Money/9.png +0 -0
- data/app/assets/images/image_authentication/People/1.png +0 -0
- data/app/assets/images/image_authentication/People/10.png +0 -0
- data/app/assets/images/image_authentication/People/11.png +0 -0
- data/app/assets/images/image_authentication/People/12.png +0 -0
- data/app/assets/images/image_authentication/People/13.png +0 -0
- data/app/assets/images/image_authentication/People/14.png +0 -0
- data/app/assets/images/image_authentication/People/15.png +0 -0
- data/app/assets/images/image_authentication/People/16.png +0 -0
- data/app/assets/images/image_authentication/People/17.png +0 -0
- data/app/assets/images/image_authentication/People/18.png +0 -0
- data/app/assets/images/image_authentication/People/19.png +0 -0
- data/app/assets/images/image_authentication/People/2.png +0 -0
- data/app/assets/images/image_authentication/People/20.png +0 -0
- data/app/assets/images/image_authentication/People/3.png +0 -0
- data/app/assets/images/image_authentication/People/4.png +0 -0
- data/app/assets/images/image_authentication/People/5.png +0 -0
- data/app/assets/images/image_authentication/People/6.png +0 -0
- data/app/assets/images/image_authentication/People/7.png +0 -0
- data/app/assets/images/image_authentication/People/8.png +0 -0
- data/app/assets/images/image_authentication/People/9.png +0 -0
- data/app/assets/images/image_authentication/Shoes/1.png +0 -0
- data/app/assets/images/image_authentication/Shoes/10.png +0 -0
- data/app/assets/images/image_authentication/Shoes/11.png +0 -0
- data/app/assets/images/image_authentication/Shoes/12.png +0 -0
- data/app/assets/images/image_authentication/Shoes/13.png +0 -0
- data/app/assets/images/image_authentication/Shoes/14.png +0 -0
- data/app/assets/images/image_authentication/Shoes/15.png +0 -0
- data/app/assets/images/image_authentication/Shoes/16.png +0 -0
- data/app/assets/images/image_authentication/Shoes/17.png +0 -0
- data/app/assets/images/image_authentication/Shoes/18.png +0 -0
- data/app/assets/images/image_authentication/Shoes/19.png +0 -0
- data/app/assets/images/image_authentication/Shoes/2.png +0 -0
- data/app/assets/images/image_authentication/Shoes/20.png +0 -0
- data/app/assets/images/image_authentication/Shoes/3.png +0 -0
- data/app/assets/images/image_authentication/Shoes/4.png +0 -0
- data/app/assets/images/image_authentication/Shoes/5.png +0 -0
- data/app/assets/images/image_authentication/Shoes/6.png +0 -0
- data/app/assets/images/image_authentication/Shoes/7.png +0 -0
- data/app/assets/images/image_authentication/Shoes/8.png +0 -0
- data/app/assets/images/image_authentication/Shoes/9.png +0 -0
- data/app/assets/images/image_authentication/Telephones/1.png +0 -0
- data/app/assets/images/image_authentication/Telephones/10.png +0 -0
- data/app/assets/images/image_authentication/Telephones/11.png +0 -0
- data/app/assets/images/image_authentication/Telephones/12.png +0 -0
- data/app/assets/images/image_authentication/Telephones/13.png +0 -0
- data/app/assets/images/image_authentication/Telephones/14.png +0 -0
- data/app/assets/images/image_authentication/Telephones/15.png +0 -0
- data/app/assets/images/image_authentication/Telephones/16.png +0 -0
- data/app/assets/images/image_authentication/Telephones/17.png +0 -0
- data/app/assets/images/image_authentication/Telephones/18.png +0 -0
- data/app/assets/images/image_authentication/Telephones/19.png +0 -0
- data/app/assets/images/image_authentication/Telephones/2.png +0 -0
- data/app/assets/images/image_authentication/Telephones/20.png +0 -0
- data/app/assets/images/image_authentication/Telephones/3.png +0 -0
- data/app/assets/images/image_authentication/Telephones/4.png +0 -0
- data/app/assets/images/image_authentication/Telephones/5.png +0 -0
- data/app/assets/images/image_authentication/Telephones/6.png +0 -0
- data/app/assets/images/image_authentication/Telephones/7.png +0 -0
- data/app/assets/images/image_authentication/Telephones/8.png +0 -0
- data/app/assets/images/image_authentication/Telephones/9.png +0 -0
- data/app/assets/images/image_authentication/Trains/1.png +0 -0
- data/app/assets/images/image_authentication/Trains/10.png +0 -0
- data/app/assets/images/image_authentication/Trains/11.png +0 -0
- data/app/assets/images/image_authentication/Trains/12.png +0 -0
- data/app/assets/images/image_authentication/Trains/13.png +0 -0
- data/app/assets/images/image_authentication/Trains/14.png +0 -0
- data/app/assets/images/image_authentication/Trains/15.png +0 -0
- data/app/assets/images/image_authentication/Trains/16.png +0 -0
- data/app/assets/images/image_authentication/Trains/17.png +0 -0
- data/app/assets/images/image_authentication/Trains/18.png +0 -0
- data/app/assets/images/image_authentication/Trains/19.png +0 -0
- data/app/assets/images/image_authentication/Trains/2.png +0 -0
- data/app/assets/images/image_authentication/Trains/20.png +0 -0
- data/app/assets/images/image_authentication/Trains/3.png +0 -0
- data/app/assets/images/image_authentication/Trains/4.png +0 -0
- data/app/assets/images/image_authentication/Trains/5.png +0 -0
- data/app/assets/images/image_authentication/Trains/6.png +0 -0
- data/app/assets/images/image_authentication/Trains/7.png +0 -0
- data/app/assets/images/image_authentication/Trains/8.png +0 -0
- data/app/assets/images/image_authentication/Trains/9.png +0 -0
- data/app/assets/javascripts/.DS_Store +0 -0
- data/app/assets/javascripts/image_authentication/image_authentication.coffee.erb +22 -0
- data/app/assets/stylesheets/.DS_Store +0 -0
- data/app/assets/stylesheets/image_authentication/image_authentication.scss +20 -0
- data/app/controllers/devise/image_authentication_controller.rb +92 -0
- data/app/views/devise/image_authentication/_image_grid.html.erb +11 -0
- data/app/views/devise/image_authentication/confirm.html.erb +13 -0
- data/app/views/devise/image_authentication/disable.html.erb +0 -0
- data/app/views/devise/image_authentication/enable.html.erb +14 -0
- data/app/views/devise/image_authentication/locked.html.erb +8 -0
- data/app/views/devise/image_authentication/show.html.erb +13 -0
- data/config/locales/en.yml +7 -0
- data/image_authentication.gemspec +23 -0
- data/lib/.DS_Store +0 -0
- data/lib/generators/.DS_Store +0 -0
- data/lib/generators/active_record/image_authentication_generator.rb +14 -0
- data/lib/generators/active_record/templates/migration.rb +8 -0
- data/lib/generators/image_authentication/image_authentication_generator.rb +17 -0
- data/lib/image_authentication/controllers/helpers.rb +36 -0
- data/lib/image_authentication/hooks/image_authentication.rb +5 -0
- data/lib/image_authentication/models/image_authenticatable.rb +60 -0
- data/lib/image_authentication/rails.rb +7 -0
- data/lib/image_authentication/routes.rb +19 -0
- data/lib/image_authentication/version.rb +3 -0
- data/lib/image_authentication.rb +26 -0
- metadata +513 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
.image-authentication {
|
2
|
+
width: 730px;
|
3
|
+
}
|
4
|
+
|
5
|
+
#auth-images {
|
6
|
+
margin: 0 auto;
|
7
|
+
border-collapse: collapse;
|
8
|
+
|
9
|
+
td {
|
10
|
+
padding: 5px;
|
11
|
+
}
|
12
|
+
|
13
|
+
img {
|
14
|
+
border: 3px solid #f1f1f1;
|
15
|
+
}
|
16
|
+
|
17
|
+
img.selected {
|
18
|
+
border: 3px solid #66cc33;
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class Devise::ImageAuthenticationController < DeviseController
|
2
|
+
|
3
|
+
prepend_before_filter :authenticate_scope!
|
4
|
+
before_filter :prepare_and_validate, :handle_image_authentication
|
5
|
+
before_filter :setup_auth_categories, :only => [ :confirm, :show ]
|
6
|
+
|
7
|
+
def enable
|
8
|
+
@auth_categories = resource.all_auth_categories
|
9
|
+
|
10
|
+
if request.get?
|
11
|
+
session["user_return_to"] = request.referer
|
12
|
+
else
|
13
|
+
if params[:image_auth_categories] && params[:image_auth_categories].size == resource.class.maximum_categories
|
14
|
+
resource.auth_categories = params[:image_auth_categories]
|
15
|
+
resource.save
|
16
|
+
|
17
|
+
setup_auth_categories
|
18
|
+
|
19
|
+
render :action => 'confirm'
|
20
|
+
else
|
21
|
+
render :action => 'enable'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def confirm
|
27
|
+
if resource.valid_images?(params[:image_auth_categories])
|
28
|
+
resource.image_authentication_enabled = true
|
29
|
+
resource.save
|
30
|
+
|
31
|
+
redirect_to session["user_return_to"]
|
32
|
+
else
|
33
|
+
render :action => 'confirm'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def disable
|
38
|
+
resource.auth_categories_mask = nil
|
39
|
+
resource.image_authentication_enabled = false
|
40
|
+
resource.save
|
41
|
+
|
42
|
+
redirect_to :back
|
43
|
+
end
|
44
|
+
|
45
|
+
def show
|
46
|
+
return redirect_to :back if !resource.image_authentication_enabled?
|
47
|
+
end
|
48
|
+
|
49
|
+
def update
|
50
|
+
if resource.valid_images?(params[:image_auth_categories])
|
51
|
+
warden.session(resource_name)[:requires_image_authentication] = false
|
52
|
+
sign_in resource_name, resource, :bypass => true
|
53
|
+
|
54
|
+
redirect_to session["user_return_to"]
|
55
|
+
else
|
56
|
+
resource.failed_attempts += 1
|
57
|
+
resource.save
|
58
|
+
|
59
|
+
if resource.max_login_attempts?
|
60
|
+
sign_out(resource)
|
61
|
+
resource.lock_access!
|
62
|
+
|
63
|
+
render :action => 'locked'
|
64
|
+
else
|
65
|
+
setup_auth_categories
|
66
|
+
|
67
|
+
render :action => 'show'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def authenticate_scope!
|
75
|
+
self.resource = send("current_#{resource_name}")
|
76
|
+
end
|
77
|
+
|
78
|
+
def prepare_and_validate
|
79
|
+
redirect_to :root and return if resource.nil?
|
80
|
+
|
81
|
+
if resource.max_login_attempts?
|
82
|
+
sign_out(resource)
|
83
|
+
resource.lock_access!
|
84
|
+
render :action => 'locked'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def setup_auth_categories
|
89
|
+
@auth_categories = resource.all_auth_categories
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<table id="auth-images">
|
2
|
+
<% @auth_categories.in_groups_of(Math.sqrt(@auth_categories.size).ceil, false) do |group| %>
|
3
|
+
<tr>
|
4
|
+
<% group.each do |cat| %>
|
5
|
+
<td>
|
6
|
+
<%= image_tag("image_authentication/#{cat}/#{rand(1..20)}.png", :class => cat) %>
|
7
|
+
</td>
|
8
|
+
<% end %>
|
9
|
+
</tr>
|
10
|
+
<% end %>
|
11
|
+
</table>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="image-authentication">
|
2
|
+
<h2><%= t(:please_confirm_your_selection) %></h2>
|
3
|
+
|
4
|
+
<%= render :partial => "devise/image_authentication/image_grid" %>
|
5
|
+
|
6
|
+
<%= form_for(resource, :url => confirm_user_image_authentication_url, :html => { :id => 'auth-form' }) do |form| %>
|
7
|
+
<fieldset></fieldset>
|
8
|
+
|
9
|
+
<div class="form-actions">
|
10
|
+
<%= submit_tag("Confirm Selection", :class => 'btn btn-success') %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="image-authentication">
|
2
|
+
<h2><%= t(:please_choose_your_images) %></h2>
|
3
|
+
<h3><%= t(:choose_a_maximum_of, :count => User.maximum_categories) %></h3>
|
4
|
+
|
5
|
+
<%= render :partial => "devise/image_authentication/image_grid" %>
|
6
|
+
|
7
|
+
<%= form_for(resource, :url => enable_user_image_authentication_url, :html => { :id => 'auth-form', :method => :put }) do |form| %>
|
8
|
+
<fieldset></fieldset>
|
9
|
+
|
10
|
+
<div class="form-actions">
|
11
|
+
<%= submit_tag(t(:confirm_selection), :class => 'btn btn-success') %>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="image-authentication">
|
2
|
+
<h2><%= t(:please_select_your_images) %></h2>
|
3
|
+
|
4
|
+
<%= render :partial => "devise/image_authentication/image_grid" %>
|
5
|
+
|
6
|
+
<%= form_for(resource, :url => user_image_authentication_url, :html => { :id => 'auth-form', :method => :put }) do |form| %>
|
7
|
+
<fieldset></fieldset>
|
8
|
+
|
9
|
+
<div class="form-actions">
|
10
|
+
<%= submit_tag(t(:confirm_selection), :class => 'btn btn-success') %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
en:
|
2
|
+
your_account_has_now_been_locked: "Your account has now been locked for 2 hours"
|
3
|
+
please_select_your_images: "Please select your images"
|
4
|
+
confirm_selection: "Confirm Selection"
|
5
|
+
please_choose_your_images: "Please choose your image selection"
|
6
|
+
please_confirm_your_selection: "Please confirm your image selection"
|
7
|
+
choose_a_maximum_of: "Choose a maximum of %{count} images"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "image_authentication/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "image_authentication"
|
7
|
+
s.version = ImageAuthentication::VERSION.dup
|
8
|
+
s.authors = ["Kieran Johnson"]
|
9
|
+
s.email = ["kieran@invisiblelines.com"]
|
10
|
+
s.homepage = "https://github.com/invisiblelines/image_authentication"
|
11
|
+
s.summary = %q{Image authentication extension for devise}
|
12
|
+
s.description = "Provides secondary authentication by asking the user to select their chosen images"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_runtime_dependency 'rails', '>= 3.1.1'
|
20
|
+
s.add_runtime_dependency 'devise'
|
21
|
+
|
22
|
+
s.add_development_dependency 'bundler'
|
23
|
+
end
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Generators
|
5
|
+
class ImageAuthenticationGenerator < ActiveRecord::Generators::Base
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def copy_image_authentication_migration
|
9
|
+
migration_template "migration.rb", "db/migrate/image_authentication_add_to_#{table_name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ImageAuthentication
|
2
|
+
module Generators
|
3
|
+
class ImageAuthenticationGenerator < Rails::Generators::NamedBase
|
4
|
+
namespace "image_authentication"
|
5
|
+
|
6
|
+
desc "Adds :image_authenticable directive in the given model. It also generates an active record migration."
|
7
|
+
|
8
|
+
def inject_image_authentication_content
|
9
|
+
path = File.join("app", "models", "#{file_path}.rb")
|
10
|
+
inject_into_file(path, "image_authenticatable, :", :after => "devise :") if File.exists?(path)
|
11
|
+
end
|
12
|
+
|
13
|
+
hook_for :orm
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ImageAuthentication
|
2
|
+
module Controllers
|
3
|
+
module Helpers
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_filter :handle_image_authentication
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def handle_image_authentication
|
13
|
+
unless devise_controller?
|
14
|
+
Devise.mappings.keys.flatten.any? do |scope|
|
15
|
+
if signed_in?(scope) and warden.session(scope)[:requires_image_authentication]
|
16
|
+
handle_failed_image_authentication(scope)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def handle_failed_image_authentication(scope)
|
23
|
+
if request.format.present? and request.format.html?
|
24
|
+
session["#{scope}_return_to"] = request.path if request.get?
|
25
|
+
|
26
|
+
scope = Devise::Mapping.find_scope!(scope)
|
27
|
+
path = send("#{scope}_image_authentication_path")
|
28
|
+
redirect_to path
|
29
|
+
else
|
30
|
+
render :nothing => true, :status => :unauthorized
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'image_authentication/hooks/image_authentication'
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Models
|
5
|
+
module ImageAuthenticatable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
Categories = [
|
9
|
+
'Aeroplanes',
|
10
|
+
'Beverages',
|
11
|
+
'Bicycles',
|
12
|
+
'Birds',
|
13
|
+
'Boats',
|
14
|
+
'Cars',
|
15
|
+
'Cats',
|
16
|
+
'Clocks',
|
17
|
+
'Dogs',
|
18
|
+
'Fish',
|
19
|
+
'Flowers',
|
20
|
+
'Food',
|
21
|
+
'Furniture',
|
22
|
+
'Houses',
|
23
|
+
'Insects',
|
24
|
+
'Money',
|
25
|
+
'People',
|
26
|
+
'Shoes',
|
27
|
+
'Telephones',
|
28
|
+
'Trains'
|
29
|
+
]
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
::Devise::Models.config(self, :lock_after_failed_attempts, :number_of_categories, :maximum_categories)
|
33
|
+
end
|
34
|
+
|
35
|
+
def auth_categories=(categories)
|
36
|
+
self.auth_categories_mask = (categories & Categories).map { |c| 2**Categories.index(c) }.sum
|
37
|
+
end
|
38
|
+
|
39
|
+
def auth_categories
|
40
|
+
Categories.reject { |c| ((auth_categories_mask || 0 ) & 2**Categories.index(c)).zero? }
|
41
|
+
end
|
42
|
+
|
43
|
+
def requires_image_authentication?(request)
|
44
|
+
image_authentication_enabled?
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_images?(categories)
|
48
|
+
(auth_categories - Categories).empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
def all_auth_categories
|
52
|
+
Categories.shuffle[0..self.class.number_of_categories]
|
53
|
+
end
|
54
|
+
|
55
|
+
def max_login_attempts?
|
56
|
+
self.class.lock_after_failed_attempts && (failed_attempts >= self.class.maximum_attempts)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActionDispatch::Routing
|
2
|
+
class Mapper
|
3
|
+
protected
|
4
|
+
|
5
|
+
def devise_image_authentication(mapping, controllers)
|
6
|
+
resource :image_authentication,
|
7
|
+
:only => [:show, :update, :enable, :disable, :confirm],
|
8
|
+
:path => mapping.path_names[:image_authentication],
|
9
|
+
:controller => controllers[:image_authentication] do
|
10
|
+
get :enable, :on => :member
|
11
|
+
put :enable, :on => :member
|
12
|
+
put :disable, :on => :member
|
13
|
+
|
14
|
+
get :confirm, :on => :member
|
15
|
+
put :confirm, :on => :member
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'image_authentication/version'
|
2
|
+
require 'devise'
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Devise
|
6
|
+
mattr_accessor :lock_after_failed_attempts
|
7
|
+
@@lock_after_failed_attempts = false
|
8
|
+
|
9
|
+
mattr_accessor :number_of_categories
|
10
|
+
@@number_of_categories = 20
|
11
|
+
|
12
|
+
mattr_accessor :maximum_categories
|
13
|
+
@@maximum_categories = 3
|
14
|
+
end
|
15
|
+
|
16
|
+
module ImageAuthentication
|
17
|
+
module Controllers
|
18
|
+
autoload :Helpers, 'image_authentication/controllers/helpers'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Devise.add_module :image_authenticatable, :model => 'image_authentication/models/image_authenticatable', :controller => :image_authentication, :route => :image_authentication
|
23
|
+
|
24
|
+
require 'image_authentication/routes'
|
25
|
+
require 'image_authentication/models/image_authenticatable'
|
26
|
+
require 'image_authentication/rails'
|