├── .gitignore ├── DEPENDENCY_LICENSES.md ├── INSTALL.md ├── LICENSE.txt ├── NOTICE.md ├── README.md ├── apache_conf ├── ideaworks_api.conf └── ideaworks_web.conf ├── backend └── ideaworks │ ├── __init__.py │ ├── api │ ├── __init__.py │ └── tools.py │ ├── auth_addin_app │ ├── __init__.py │ ├── forms.py │ ├── models.py │ ├── static │ │ └── auth_addin_app │ │ │ ├── css │ │ │ ├── global.css │ │ │ ├── normalize.css │ │ │ └── smoothness │ │ │ │ ├── images │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ ├── ui-icons_888888_256x240.png │ │ │ │ └── ui-icons_cd0a0a_256x240.png │ │ │ │ └── jquery-ui-1.9.2.min.css │ │ │ └── js │ │ │ ├── authForm.js │ │ │ ├── jquery-1.10.2.min.js │ │ │ ├── jquery-ui-1.9.2.min.js │ │ │ ├── jquery.cookie.js │ │ │ ├── jquery.json.min.js │ │ │ ├── modernizr-2.6.2.min.js │ │ │ └── registration.js │ ├── templatetags │ │ ├── __init__.py │ │ └── auth_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── config │ ├── __init__.py │ └── dev_rb.py │ ├── config_app │ ├── __init__.py │ ├── api.py │ ├── blah.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ └── views.py │ ├── contentapp │ ├── __init__.py │ ├── api.py │ ├── api_functions.py │ ├── authentication.py │ ├── authorization.py │ ├── documents.py │ ├── models.py │ ├── serializers.py │ ├── tests │ │ ├── __init__.py │ │ ├── feedback_tests.py │ │ └── site_content_tests.py │ └── views.py │ ├── ideasapp │ ├── __init__.py │ ├── api.py │ ├── api_functions.py │ ├── authentication.py │ ├── authorization.py │ ├── documents.py │ ├── models.py │ ├── serializers.py │ ├── tests │ │ ├── __init__.py │ │ ├── idea_tests.py │ │ ├── resource_nouns.txt │ │ └── rss_tests.py │ └── views.py │ ├── ideaworks │ ├── __init__.py │ ├── admin.py │ ├── auth_settings.py │ ├── email_settings_placeholder.py │ ├── generic_resources.py │ ├── settings.py │ ├── tastypie_settings.py │ ├── urls.py │ └── wsgi.py │ ├── logs │ └── .gitignore │ ├── manage.py │ ├── projectsapp │ ├── __init__.py │ ├── api.py │ ├── api_functions.py │ ├── authentication.py │ ├── authorization.py │ ├── documents.py │ ├── models.py │ ├── serializers.py │ ├── tests │ │ ├── __init__.py │ │ ├── project_tests.py │ │ ├── resource_nouns.txt │ │ └── rss_tests.py │ └── views.py │ ├── protective_marking_app │ ├── __init__.py │ ├── api.py │ ├── data │ │ ├── __init__.py │ │ ├── _insert_data.py │ │ ├── classifications.json │ │ ├── codewords.json │ │ ├── descriptors.json │ │ └── national_caveats.json │ ├── documents.py │ ├── models.py │ ├── serializers.py │ ├── tests │ │ ├── __init__.py │ │ └── pm_tests.py │ └── views.py │ ├── static │ ├── css │ │ ├── global.css │ │ ├── normalize.css │ │ ├── smoothness │ │ │ ├── images │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ ├── ui-icons_888888_256x240.png │ │ │ │ └── ui-icons_cd0a0a_256x240.png │ │ │ └── jquery-ui-1.9.2.min.css │ │ └── tastytools │ │ │ ├── api.doc.css │ │ │ ├── api.howto.css │ │ │ └── style.css │ ├── img │ │ └── bootstrap │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ └── js │ │ ├── registration.js │ │ └── tastytools │ │ ├── api.doc.coffee │ │ └── api.doc.js │ ├── templates │ ├── base.html │ └── registration │ │ ├── activate.html │ │ ├── activation_email.txt │ │ ├── activation_email_hmtl.txt │ │ ├── activation_email_subject.txt │ │ ├── description_snippet.html │ │ ├── homepage_placeholder.html │ │ ├── login.html │ │ ├── logout.html │ │ ├── need_an_account.html │ │ ├── password_change_done_custom.html │ │ ├── password_change_form_custom.html │ │ ├── password_reset_complete.html │ │ ├── password_reset_confirm.html │ │ ├── password_reset_done.html │ │ ├── password_reset_email.html │ │ ├── password_reset_email_as_html.html │ │ ├── password_reset_form.html │ │ ├── password_reset_subject.txt │ │ ├── prototype_snippet.html │ │ ├── registration_auto_complete.html │ │ ├── registration_complete.html │ │ ├── registration_form.html │ │ ├── registration_include.html │ │ └── terms_of_service.html │ └── user_db │ └── .placeholder_file ├── dependencies_cache └── .placeholder ├── frontend ├── .placeholder └── istarter-web │ ├── README.md │ ├── bootstrap │ └── 232 │ │ ├── css │ │ ├── bootstrap-responsive.css │ │ ├── bootstrap-responsive.min.css │ │ ├── bootstrap-select.min.css │ │ ├── bootstrap-sortable.css │ │ ├── bootstrap.css │ │ ├── bootstrap.icon-large.css │ │ └── bootstrap.min.css │ │ ├── img │ │ ├── glyphicons-halflings-white.png │ │ ├── glyphicons-halflings.png │ │ └── glyphicons.png │ │ └── js │ │ ├── bootstrap-select.min.js │ │ ├── bootstrap-sortable.js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js │ ├── css │ ├── animations.css │ ├── app.css │ ├── bootstrap-responsive.css │ ├── bootstrap-responsive.min.css │ ├── bootstrap.css │ ├── bootstrap.min.css │ ├── font-awesome │ │ ├── css │ │ │ ├── font-awesome.css │ │ │ └── font-awesome.min.css │ │ └── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ ├── national_caveats.json │ └── ng-grid.css │ ├── data │ ├── ideas │ │ ├── idea-1.json │ │ ├── idea-2.json │ │ ├── idea-3.json │ │ ├── idea-4.json │ │ ├── ideas.json │ │ ├── ideas_all.json │ │ ├── ideas_latest - Copy.json │ │ └── ideas_latest.json │ ├── protective_marking │ │ ├── classifications.json │ │ ├── codewords.json │ │ ├── descriptors.json │ │ └── national_caveats.json │ ├── site_content │ │ └── types.json │ └── tags │ │ └── tags.json │ ├── images │ ├── iStarter Logo greyscale.png │ ├── iStarter Logo long tagline.png │ ├── iStarter Logo long.png │ ├── iStarter Logo tranparent.png │ ├── iStarter Logo.png │ ├── istarter-large.png │ ├── istarter-logo.png │ └── mongoDB-logo-40.png │ ├── index.html │ ├── js │ ├── animations.js │ ├── app.js │ ├── controllers.js │ ├── directives.js │ ├── filters.js │ ├── lib │ │ ├── angular │ │ │ ├── angular-animate.min.js │ │ │ ├── angular-bootstrap-select.js │ │ │ ├── angular-cookies.min.js │ │ │ ├── angular-loader.min.js │ │ │ ├── angular-mocks.js │ │ │ ├── angular-resource.min.js │ │ │ ├── angular-route.min.js │ │ │ ├── angular-sanitize.min.js │ │ │ ├── angular-touch.min.js │ │ │ ├── angular-ui-bootstrap.min.js │ │ │ ├── angular.min.js │ │ │ ├── ng-grid.min.js │ │ │ ├── textAngular.js │ │ │ └── textAngular.min.js │ │ ├── html5shiv.js │ │ ├── jquery │ │ │ ├── jquery-1.10.2.min.js │ │ │ └── jquery.cookie.js │ │ └── respond.min.js │ └── services.js │ └── templates │ ├── docs │ ├── about.html │ └── description-of-service.html │ ├── feedback │ ├── create.html │ ├── read.html │ ├── view-sidebar.html │ └── view.html │ ├── ideas │ ├── create.html │ ├── likes-bar.html │ ├── popups.html │ ├── read.html │ └── view │ │ ├── all.html │ │ ├── grid.html │ │ ├── list.html │ │ ├── sidebar.html │ │ ├── summary.html │ │ └── switch-layout.html │ ├── logged-out.html │ ├── modals │ ├── backing.html │ ├── comment.html │ ├── dislike.html │ ├── edit-comment.html │ └── like.html │ ├── not-found.html │ ├── projects │ ├── create.html │ ├── read.html │ └── view │ │ ├── sidebar.html │ │ ├── summary.html │ │ └── switch-layout.html │ ├── site-content │ ├── create.html │ ├── index.html │ ├── read.html │ └── view.html │ ├── tags.html │ └── top-menu.html ├── readme_images ├── add_a_comment.png ├── create_an_idea.png ├── view_an_idea_details.png └── view_ideas_summary.png └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | 19 | # Javascript in front end has a lib directory 20 | #lib 21 | #lib64 22 | 23 | # Installer logs 24 | pip-log.txt 25 | 26 | # Unit test / coverage reports 27 | .coverage 28 | .tox 29 | nosetests.xml 30 | 31 | # Translations 32 | *.mo 33 | 34 | # Mr Developer 35 | .mr.developer.cfg 36 | .project 37 | .pydevproject 38 | 39 | # Hide Finder details on OSX 40 | .DS_Store 41 | 42 | # Hide xemacs backup files 43 | *~ 44 | 45 | # Django application logs 46 | *.gitignore.log 47 | 48 | # ignore project specific files 49 | *.log 50 | 51 | .spyderproject 52 | 53 | # Ignore the sql db 54 | *.db 55 | 56 | # Ignore the email settings 57 | email_settings.* -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/NOTICE.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 2 | 3 | # Ideaworks 4 | 5 | Ideaworks is a free and open source web application that allows a group of people to collate, comment on and rate ideas. The application also 6 | allows staff users to create projects, small packages of work that have developed from the ideas. 7 | 8 | It was initially designed and built by the UK Defence Science & Technology Laboratory (dstl) and released under AGPL as a prototype tool. Ideaworks was the first piece of software to be released onto Github because of its simplicity, low risk and potential benefit to the Free and Open Source software community - particularly those organising hackathons. 9 | 10 | We don’t pretend that the code is the best ever written (see [NOTICE.md](NOTICE.md) and [LICENSE.txt](LICENSE.txt) for the disclaimers), but please use it as you see fit, file bugs and enhancement issues (of which we’ll be adding a few outstanding). We very much welcome pull requests. 11 | 12 | The application is split into 2 parts: 13 | 14 | 1. A django project which provides the data API back-end and user authentication. 15 | 2. A responsive design html/js/css front-end. 16 | 17 | # Installation 18 | 19 | An installation guide is provided in this repo ([INSTALL.md](INSTALL.md)). We're also working on an Ansible script for deployment, which should be linked from this repo shortly. If you're interested in deploying an instance of ideaworks and the Ansible script isn't out yet, please get in touch. 20 | 21 | 22 | # Screenshots 23 | 24 | This instance is called iStarter - the name and logo is configurable to suit your use case. 25 | 26 | #### Create an idea 27 | ![Ideas in Ideaworks](/readme_images/create_an_idea.png?raw=true "Create An Ideas") 28 | 29 | #### A summary view of all the ideas 30 | 31 | ![Ideas in Ideaworks](/readme_images/view_ideas_summary.png?raw=true "View Idea Summary") 32 | 33 | #### View an idea - see the detail full list of comments 34 | 35 | ![Ideas in Ideaworks](/readme_images/view_an_idea_details.png?raw=true "View an Idea") 36 | 37 | #### Comment on an idea to stimulate some discussion 38 | 39 | ![Ideas in Ideaworks](/readme_images/add_a_comment.png?raw=true "Add a Comment") 40 | -------------------------------------------------------------------------------- /apache_conf/ideaworks_api.conf: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | # Allows for the serving of static files associated with this app 6 | Alias /ideaworks_api/static/ <> 7 | 8 | > > 9 | Order deny,allow 10 | Allow from all 11 | 12 | 13 | # Config for serving the wsgi parts of the app 14 | WSGIDaemonProcess /ideaworks_api python-path=: 15 | 16 | WSGISocketPrefix /var/run/wsgi 17 | WSGIScriptAlias /ideaworks_api 18 | > 19 | WSGIProcessGroup /ideaworks_api 20 | Order allow,deny 21 | Allow from all 22 | 23 | 24 | # Allow the webserver to pass the HTTP_AUTHORIZATION header 25 | WSGIPassAuthorization On 26 | 27 | #------------------------------------------------------------------------------------------------ 28 | #Here's an example 29 | 30 | # Alias /ideaworks_api/static/ /home/user/webapps/ideaworks/backend/ideaworks/static/ 31 | # 32 | # 33 | # Order deny,allow 34 | # Allow from all 35 | # 36 | # 37 | # WSGIDaemonProcess my_server.com/ideaworks_api python-path=/home/user/webapps/ideaworks/backend/ideaworks:/home/user/venvs/ideaworks_api/lib/python2.6/site-packages 38 | # 39 | # WSGISocketPrefix /var/run/wsgi 40 | # WSGIScriptAlias /ideaworks_api /home/user/webapps/ideaworks/backend/ideaworks/ideaworks/wsgi.py 41 | # 42 | # WSGIProcessGroup my_server.com/ideaworks_api 43 | # Order allow,deny 44 | # Allow from all 45 | # 46 | 47 | # WSGIPassAuthorization On 48 | #------------------------------------------------------------------------------------------------ 49 | 50 | -------------------------------------------------------------------------------- /apache_conf/ideaworks_web.conf: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | # Redirects for non-front-end components 6 | 7 | # ASSUMING: You have the backend (API, etc.) all up and running on <>/ideaworks/ 8 | 9 | # Proxy pass for the API auto documentation 10 | ProxyPass /ideaworks/api_docs/ <>/ideaworks/api_docs/ 11 | ProxyPassReverse /ideaworks/api_docs/ <>/ideaworks/api_docs/ 12 | 13 | # Proxy pass for the Django admin interface 14 | ProxyPass /ideaworks/admin/ <>/ideaworks/admin/ 15 | ProxyPassReverse /ideaworks/admin/ <>/ideaworks/admin/ 16 | 17 | # Proxy pass for the actual API 18 | ProxyPass /ideaworks/api/ <>/ideaworks/api/ 19 | ProxyPassReverse /ideaworks/api/ <>/ideaworks/api/ 20 | 21 | # Proxy pass for authentication/registration components 22 | ProxyPass /ideaworks/accounts/ <>/ideaworks/accounts/ 23 | ProxyPassReverse /ideaworks/accounts/ <>/ideaworks/accounts/ 24 | 25 | # Proxy pass for backend static content (required for registration in particular) 26 | ProxyPass /ideaworks/accounts/ <>/ideaworks/static/ 27 | ProxyPassReverse /ideaworks/accounts/ <>/ideaworks/static/ 28 | 29 | # Front-end file path config 30 | 31 | # Pointer from url path to code 32 | Alias /<> <>/<> 33 | 34 | # Permissions on the directory 35 | > > 36 | Options FollowSymLinks 37 | AllowOverride None 38 | 39 | 40 | # Catch for encoding slashes 41 | AllowEncodedSlashes On -------------------------------------------------------------------------------- /backend/ideaworks/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | import ideasapp -------------------------------------------------------------------------------- /backend/ideaworks/api/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | -------------------------------------------------------------------------------- /backend/ideaworks/api/tools.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | """ 6 | Hook up the resources via the tastytools documentation 7 | """ 8 | # Tastytools is used to automatically build API documentation 9 | from tastytools.api import Api 10 | 11 | # Create a new API that binds together the existing APIs 12 | v1_api = Api(api_name='v1') 13 | 14 | 15 | # --- IDEA API --- 16 | 17 | from ideasapp.api import IdeaResource 18 | from ideasapp.api import CommentResource 19 | from ideasapp.api import TagResource 20 | from ideasapp.api import ProtectiveMarkingResource 21 | v1_api.register(CommentResource()) 22 | v1_api.register(TagResource()) 23 | v1_api.register(ProtectiveMarkingResource()) 24 | 25 | # --- PROJECTS API --- 26 | 27 | from projectsapp.api import ProjectResource 28 | from projectsapp.api import CommentResource 29 | from projectsapp.api import TagResource 30 | from projectsapp.api import ProtectiveMarkingResource 31 | v1_api.register(ProjectResource()) 32 | v1_api.register(IdeaResource()) 33 | v1_api.register(CommentResource()) 34 | v1_api.register(TagResource()) 35 | v1_api.register(ProtectiveMarkingResource()) 36 | 37 | 38 | # --- CONTENT API --- 39 | 40 | from contentapp.api import ProtectiveMarkingResource 41 | from contentapp.api import SiteContentResource 42 | from contentapp.api import FeedbackResource 43 | from contentapp.api import FeedbackCommentResource 44 | v1_api.register(SiteContentResource()) 45 | v1_api.register(FeedbackResource()) 46 | v1_api.register(FeedbackCommentResource()) 47 | v1_api.register(ProtectiveMarkingResource()) 48 | 49 | 50 | # --- Protective Marking API --- 51 | 52 | from protective_marking_app.api import ClassificationResource 53 | from protective_marking_app.api import DescriptorResource 54 | from protective_marking_app.api import CodewordResource 55 | from protective_marking_app.api import NationalCaveatResource 56 | from protective_marking_app.api import CssStyleResource 57 | v1_api.register(ClassificationResource()) 58 | v1_api.register(DescriptorResource()) 59 | v1_api.register(CodewordResource()) 60 | v1_api.register(NationalCaveatResource()) 61 | v1_api.register(CssStyleResource()) 62 | 63 | 64 | # --- CONFIG/SETTINGS API --- 65 | 66 | from config_app.api import ConfigResource 67 | v1_api.register(ConfigResource()) 68 | 69 | -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/forms.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from django import forms 6 | from django.utils.translation import ugettext_lazy as _ 7 | from registration_email.forms import EmailRegistrationForm 8 | 9 | class RegistrationEmailAndFormTermsOfService(EmailRegistrationForm): 10 | """ 11 | Subclass of ``EmailRegistrationForm`` which adds:- 12 | 1. A required checkbox for agreeing to a site's Terms of Service. 13 | 2. First name 14 | 3. Last name 15 | 4. Organisation 16 | 5. Team 17 | 18 | """ 19 | tos = forms.BooleanField(widget=forms.CheckboxInput, 20 | label=_(u'I have read and agree to the Terms of Service'), 21 | help_text="In order to use this service you are required to read and agree to the terms of service.", 22 | error_messages={'required': _("You must agree to the terms to register")}) 23 | 24 | first_name = forms.CharField(widget=forms.TextInput(), 25 | label=_(u'First name'), 26 | help_text="Please enter your first name.", 27 | required=False) 28 | 29 | last_name = forms.CharField(widget=forms.TextInput(), 30 | label=_('Last name'), 31 | help_text="Please enter your last name.", 32 | required=False) 33 | 34 | organisation = forms.CharField(widget=forms.TextInput(), 35 | label=_('Organisation'), 36 | help_text="Please enter the name of your organisation.", 37 | required=False) 38 | 39 | team = forms.CharField(widget=forms.TextInput(), 40 | label=_('Team'), 41 | help_text="Please enter the name of your team.", 42 | required=False) 43 | -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/models.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from django import forms 6 | 7 | # This set of imports and the class allows us to use the registration terms of service class 8 | from registration.backends.default.views import RegistrationView 9 | 10 | # For the signal 11 | from django.dispatch import receiver 12 | from registration.signals import user_registered 13 | 14 | # This added in so that API key is created on account registration. Issue #IDEA-39. 15 | from django.contrib.auth.models import User 16 | from django.db import models 17 | from tastypie.models import create_api_key 18 | 19 | models.signals.post_save.connect(create_api_key, sender=User) 20 | 21 | 22 | class AuthCustomisedRegistrationView(RegistrationView): 23 | """ 24 | Custom model that includes terms of service, first and last name and organisation info 25 | """ 26 | 27 | tos = forms.BooleanField() 28 | first_name = forms.CharField(required=False) 29 | last_name = forms.CharField(required=False) 30 | organisation = forms.CharField(required=False) 31 | team = forms.CharField(required=False) 32 | 33 | @receiver(user_registered) 34 | def user_registered_handler(sender, user, request, **kwargs): 35 | """ 36 | A signal handler that receives all the parameters from the validated form. 37 | """ 38 | user.first_name = request.POST.get('first_name') 39 | user.last_name = request.POST.get('last_name') 40 | user.organisation = request.POST.get('organisation') 41 | user.team = request.POST.get('team') 42 | user.save() 43 | -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/auth_addin_app/static/auth_addin_app/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/js/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.4.0 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD. Register as anonymous module. 11 | define(['jquery'], factory); 12 | } else { 13 | // Browser globals. 14 | factory(jQuery); 15 | } 16 | }(function ($) { 17 | 18 | var pluses = /\+/g; 19 | 20 | function encode(s) { 21 | return config.raw ? s : encodeURIComponent(s); 22 | } 23 | 24 | function decode(s) { 25 | return config.raw ? s : decodeURIComponent(s); 26 | } 27 | 28 | function stringifyCookieValue(value) { 29 | return encode(config.json ? JSON.stringify(value) : String(value)); 30 | } 31 | 32 | function parseCookieValue(s) { 33 | if (s.indexOf('"') === 0) { 34 | // This is a quoted cookie as according to RFC2068, unescape... 35 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 36 | } 37 | 38 | try { 39 | // Replace server-side written pluses with spaces. 40 | // If we can't decode the cookie, ignore it, it's unusable. 41 | s = decodeURIComponent(s.replace(pluses, ' ')); 42 | } catch(e) { 43 | return; 44 | } 45 | 46 | try { 47 | // If we can't parse the cookie, ignore it, it's unusable. 48 | return config.json ? JSON.parse(s) : s; 49 | } catch(e) {} 50 | } 51 | 52 | function read(s, converter) { 53 | var value = config.raw ? s : parseCookieValue(s); 54 | return $.isFunction(converter) ? converter(value) : value; 55 | } 56 | 57 | var config = $.cookie = function (key, value, options) { 58 | 59 | // Write 60 | if (value !== undefined && !$.isFunction(value)) { 61 | options = $.extend({}, config.defaults, options); 62 | 63 | if (typeof options.expires === 'number') { 64 | var days = options.expires, t = options.expires = new Date(); 65 | t.setDate(t.getDate() + days); 66 | } 67 | 68 | return (document.cookie = [ 69 | encode(key), '=', stringifyCookieValue(value), 70 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 71 | options.path ? '; path=' + options.path : '', 72 | options.domain ? '; domain=' + options.domain : '', 73 | options.secure ? '; secure' : '' 74 | ].join('')); 75 | } 76 | 77 | // Read 78 | 79 | var result = key ? undefined : {}; 80 | 81 | // To prevent the for loop in the first place assign an empty array 82 | // in case there are no cookies at all. Also prevents odd result when 83 | // calling $.cookie(). 84 | var cookies = document.cookie ? document.cookie.split('; ') : []; 85 | 86 | for (var i = 0, l = cookies.length; i < l; i++) { 87 | var parts = cookies[i].split('='); 88 | var name = decode(parts.shift()); 89 | var cookie = parts.join('='); 90 | 91 | if (key && key === name) { 92 | // If second argument (value) is a function it's a converter... 93 | result = read(cookie, value); 94 | break; 95 | } 96 | 97 | // Prevent storing a cookie that we couldn't decode. 98 | if (!key && (cookie = read(cookie)) !== undefined) { 99 | result[name] = cookie; 100 | } 101 | } 102 | 103 | return result; 104 | }; 105 | 106 | config.defaults = {}; 107 | 108 | $.removeCookie = function (key, options) { 109 | if ($.cookie(key) !== undefined) { 110 | // Must not alter options, thus extending a fresh object... 111 | $.cookie(key, '', $.extend({}, options, { expires: -1 })); 112 | return true; 113 | } 114 | return false; 115 | }; 116 | 117 | })); 118 | -------------------------------------------------------------------------------- /backend/ideaworks/auth_addin_app/static/auth_addin_app/js/jquery.json.min.js: -------------------------------------------------------------------------------- 1 | var JSON;if(!JSON){JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i',] 33 | 34 | """ -------------------------------------------------------------------------------- /backend/ideaworks/ideaworks/email_settings_placeholder.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | """ 6 | Settings for connecting to an email server. 7 | """ 8 | 9 | #Required email settings 10 | DEFAULT_FROM_EMAIL = '' 11 | EMAIL_HOST_USER = '' 12 | EMAIL_HOST_PASSWORD = '' 13 | EMAIL_PORT = 587 14 | EMAIL_HOST = '' 15 | EMAIL_USE_TLS = True 16 | FEEDBACK_RECIPIENTS = ['',] 17 | -------------------------------------------------------------------------------- /backend/ideaworks/ideaworks/generic_resources.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from django.http import HttpResponse 6 | 7 | from tastypie_mongoengine import resources 8 | from tastypie.exceptions import ImmediateHttpResponse 9 | from tastypie import http 10 | 11 | class BaseCorsResource(resources.MongoEngineResource): 12 | """ 13 | Class implementing CORS, @danigosa author and taken from this blog: 14 | http://codeispoetry.me/index.php/make-your-django-tastypie-api-cross-domain/ 15 | Inheriting this in our models allows requests to the API from any domain, which is useful for the front-end. 16 | """ 17 | 18 | def create_response(self, *args, **kwargs): 19 | response = super(BaseCorsResource, self).create_response(*args, **kwargs) 20 | response['Access-Control-Allow-Origin'] = '*' 21 | response['Access-Control-Allow-Headers'] = 'Content-Type' 22 | return response 23 | 24 | def method_check(self, request, allowed=None): 25 | """ 26 | For this base resource, check that the HTTP request method is permitted. 27 | """ 28 | if allowed is None: 29 | allowed = [] 30 | 31 | # Get the method (GET/POST/PUT, etc) from the django request object 32 | request_method = request.method.lower() 33 | allows = ','.join([str(i).upper() for i in allowed]) 34 | 35 | if request_method == 'options': 36 | response = HttpResponse(allows) 37 | response['Access-Control-Allow-Origin'] = '*' 38 | response['Access-Control-Allow-Headers'] = 'Content-Type' 39 | response['Allow'] = allows 40 | raise ImmediateHttpResponse(response=response) 41 | 42 | if not request_method in allowed: 43 | response = http.HttpMethodNotAllowed(allows) 44 | response['Allow'] = allows 45 | raise ImmediateHttpResponse(response=response) 46 | 47 | return request_method -------------------------------------------------------------------------------- /backend/ideaworks/ideaworks/urls.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from django.conf.urls import patterns, include, url 6 | from django.conf.urls.defaults import * 7 | from tastypie.api import Api 8 | 9 | # These 2 lines enable the django admin interface and objects 10 | from django.contrib import admin 11 | admin.autodiscover() 12 | 13 | # Api() is now instantiated in api/tools.py 14 | from api.tools import v1_api 15 | 16 | urlpatterns = patterns('', 17 | 18 | # API 19 | (r'^api/', include(v1_api.urls)), 20 | 21 | # Admin interface 22 | url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 23 | url(r'^admin/', include(admin.site.urls)), 24 | 25 | # API Documentation 26 | # Navigate to docs/doc 27 | #TODO: Make this clearer and more coherent across ideas and projects 28 | (r'^api_docs/', include('tastytools.urls'), {'api_name': v1_api.api_name}), 29 | 30 | # Authentication, registration, etc. 31 | url(r'^', include('auth_addin_app.urls')), 32 | 33 | 34 | ) 35 | 36 | 37 | #from django.contrib.staticfiles.urls import staticfiles_urlpatterns 38 | #urlpatterns += staticfiles_urlpatterns() 39 | -------------------------------------------------------------------------------- /backend/ideaworks/ideaworks/wsgi.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | """ 6 | WSGI config for ideaworks project. 7 | 8 | This module contains the WSGI application used by Django's development server 9 | and any production WSGI deployments. It should expose a module-level variable 10 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 11 | this application via the ``WSGI_APPLICATION`` setting. 12 | 13 | Usually you will have the standard Django WSGI application here, but it also 14 | might make sense to replace the whole Django WSGI application with a custom one 15 | that later delegates to the Django one. For example, you could introduce WSGI 16 | middleware here, or combine a Django application with an application of another 17 | framework. 18 | 19 | """ 20 | import os 21 | 22 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ideaworks.settings") 23 | 24 | # This application object is used by any WSGI server configured to use this 25 | # file. This includes Django's development server, if the WSGI_APPLICATION 26 | # setting points here. 27 | from django.core.wsgi import get_wsgi_application 28 | application = get_wsgi_application() 29 | 30 | # Apply WSGI middleware here. 31 | # from helloworld.wsgi import HelloWorldApplication 32 | # application = HelloWorldApplication(application) 33 | -------------------------------------------------------------------------------- /backend/ideaworks/logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/logs/.gitignore -------------------------------------------------------------------------------- /backend/ideaworks/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ideaworks.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | 12 | -------------------------------------------------------------------------------- /backend/ideaworks/projectsapp/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | import api -------------------------------------------------------------------------------- /backend/ideaworks/projectsapp/authentication.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from tastypie.authentication import ApiKeyAuthentication 6 | from tastypie.compat import User 7 | 8 | from tastypie.http import HttpUnauthorized 9 | from tastypie.compat import username_field 10 | 11 | 12 | #------------------------------------------------------------------------ 13 | 14 | class CustomApiKeyAuthentication(ApiKeyAuthentication): 15 | """ 16 | Authenticates everyone if the request is GET otherwise performs 17 | ApiKeyAuthentication. 18 | """ 19 | 20 | def _unauthorized(self): 21 | return HttpUnauthorized() 22 | 23 | def extract_credentials(self, request): 24 | if request.META.get('HTTP_AUTHORIZATION') and request.META['HTTP_AUTHORIZATION'].lower().startswith('apikey '): 25 | (auth_type, data) = request.META['HTTP_AUTHORIZATION'].split() 26 | 27 | if auth_type.lower() != 'apikey': 28 | raise ValueError("Incorrect authorization header.") 29 | 30 | username, api_key = data.split(':', 1) 31 | else: 32 | username = request.GET.get('username') or request.POST.get('username') 33 | api_key = request.GET.get('api_key') or request.POST.get('api_key') 34 | 35 | return username, api_key 36 | 37 | def is_authenticated(self, request, **kwargs): 38 | """ 39 | Finds the user and checks their API key. 40 | Should return either ``True`` if allowed, ``False`` if not or an 41 | ``HttpResponse`` if you need something custom. 42 | """ 43 | 44 | try: 45 | username, api_key = self.extract_credentials(request) 46 | except ValueError: 47 | if request.method == 'GET': 48 | return True 49 | else: 50 | self._unauthorized() 51 | 52 | if not username or not api_key: 53 | if request.method == 'GET': 54 | return True 55 | else: 56 | return self._unauthorized() 57 | 58 | try: 59 | lookup_kwargs = {username_field: username} 60 | user = User.objects.get(**lookup_kwargs) 61 | except (User.DoesNotExist, User.MultipleObjectsReturned): 62 | 63 | # This handles the case where the client is using the correct header, but the header content is 'undefined' 64 | # If this happens for simple GETs the we let it pass, otherwise we return unauthorized. 65 | if request.method == 'GET': 66 | return True 67 | else: 68 | return self._unauthorized() 69 | 70 | if not self.check_active(user): 71 | return False 72 | 73 | key_auth_check = self.get_key(user, api_key) 74 | if key_auth_check and not isinstance(key_auth_check, HttpUnauthorized): 75 | request.user = user 76 | 77 | return key_auth_check 78 | 79 | def get_key(self, user, api_key): 80 | """ 81 | Attempts to find the API key for the user. Uses ``ApiKey`` by default 82 | but can be overridden. 83 | """ 84 | from tastypie.models import ApiKey 85 | 86 | try: 87 | ApiKey.objects.get(user=user, key=api_key) 88 | except ApiKey.DoesNotExist: 89 | return self._unauthorized() 90 | 91 | return True 92 | 93 | def get_identifier(self, request): 94 | """ 95 | Provides a unique string identifier for the requestor. 96 | 97 | This implementation returns the user's username. 98 | """ 99 | 100 | username, api_key = self.extract_credentials(request) 101 | return username or 'nouser' 102 | 103 | -------------------------------------------------------------------------------- /backend/ideaworks/projectsapp/models.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | ''' 6 | 7 | This is already provided in the ideasapp 8 | 9 | http://stackoverflow.com/questions/12485053/tastypie-apikey-authentication 10 | and this 11 | http://stackoverflow.com/questions/17508912/django-tastypie-why-are-api-keys-useful-and-how-to-support-multiple-auth-scheme 12 | 13 | Alternatively - and hence why the bit is commented, have used this: 14 | http://django-tastypie.readthedocs.org/en/latest/cookbook.html#adding-to-the-django-admin 15 | 16 | from django.contrib.auth.models import User 17 | from django.db import models 18 | from tastypie.models import create_api_key 19 | 20 | models.signals.post_save.connect(create_api_key, sender=User) 21 | ''' 22 | -------------------------------------------------------------------------------- /backend/ideaworks/projectsapp/tests/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from project_tests import Test_Simple_GET_Project_API 6 | from project_tests import Test_Filtered_GET_Project_API 7 | from project_tests import Test_Filtered_GET_Project_API_modified_status 8 | from project_tests import Test_POST_Project_API 9 | from project_tests import Test_Project_Sorting 10 | from project_tests import Test_GET_tags 11 | from project_tests import Test_Back_Actions 12 | from project_tests import Test_Check_Modified 13 | from project_tests import Test_Data_Level_Responses 14 | from project_tests import Test_Basic_Authentication_Functions 15 | from project_tests import Test_Simple_GET_Project_specifics 16 | from project_tests import Test_Contributor_Naming 17 | from project_tests import Test_Project_With_Protective_Markings 18 | from project_tests import Test_Get_All_PMs 19 | from project_tests import Test_Max_PM_in_Meta 20 | from project_tests import Test_Deletes 21 | from project_tests import Test_Get_Non_Standard_Fields 22 | 23 | # Basic functional tests against the API support functions 24 | from project_tests import Test_Basic_API_Functions 25 | 26 | # Tests to cover RSS behaviour 27 | from rss_tests import Test_Project_RSS_Format 28 | from rss_tests import Test_Project_RSS_Modifications 29 | from rss_tests import Test_Project_RSS_Filtering 30 | -------------------------------------------------------------------------------- /backend/ideaworks/projectsapp/views.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | import documents -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/api.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | from tastypie.authentication import Authentication 6 | from tastypie.authorization import Authorization 7 | 8 | from ideaworks.generic_resources import BaseCorsResource 9 | from ideaworks.settings import * 10 | 11 | from tastypie_mongoengine import resources 12 | from protective_marking_app import documents as documents 13 | 14 | from protective_marking_app.serializers import PrettyJSONSerializer 15 | 16 | from tastypie_mongoengine import fields as mongo_fields 17 | 18 | class GenericPMResource(BaseCorsResource, resources.MongoEngineResource): 19 | 20 | class Meta: 21 | allowed_methods = ['get'] 22 | serializer = PrettyJSONSerializer() 23 | authentication = Authentication() 24 | authorization = Authorization() 25 | 26 | def determine_format(self, request): 27 | """ Override the default format, so that format=json is not required """ 28 | content_types = {'json': 'application/json', 29 | 'jsonp': 'text/javascript', 30 | 'xml': 'application/xml', 31 | 'yaml': 'text/yaml', 32 | 'html': 'text/html', 33 | 'plist': 'application/x-plist', 34 | 'csv': 'text/csv'} 35 | 36 | format = request.GET.get('format', None) 37 | if format == None: 38 | return 'application/json' 39 | else: 40 | return content_types[format] 41 | 42 | #----------------------------------------------------------------------------- 43 | 44 | class CssStyleResource(GenericPMResource): 45 | 46 | class Meta(GenericPMResource.Meta): 47 | object_class = documents.CssStyle 48 | resource_name = 'css_style' 49 | 50 | #----------------------------------------------------------------------------- 51 | 52 | class ClassificationResource(GenericPMResource): 53 | 54 | css_style = mongo_fields.EmbeddedDocumentField(embedded='protective_marking_app.api.CssStyleResource', attribute='css_style', help_text='CSS Style associated with this protective marking element', null=True) 55 | 56 | class Meta(GenericPMResource.Meta): 57 | queryset = documents.Classification.objects.all() 58 | resource_name = 'classification' 59 | 60 | #----------------------------------------------------------------------------- 61 | 62 | class DescriptorResource(GenericPMResource): 63 | class Meta(GenericPMResource.Meta): 64 | queryset = documents.Descriptor.objects.all() 65 | resource_name = 'descriptor' 66 | 67 | #----------------------------------------------------------------------------- 68 | 69 | class CodewordResource(GenericPMResource): 70 | class Meta(GenericPMResource.Meta): 71 | queryset = documents.Codeword.objects.all() 72 | resource_name = 'codeword' 73 | 74 | #----------------------------------------------------------------------------- 75 | 76 | class NationalCaveatResource(GenericPMResource): 77 | class Meta(GenericPMResource.Meta): 78 | queryset = documents.NationalCaveat.objects.all() 79 | resource_name = 'national_caveat' 80 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/data/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/data/classifications.json: -------------------------------------------------------------------------------- 1 | [{"classification" : "PUBLIC", 2 | "abbreviation" : "PU", 3 | "comment" : "", 4 | "source" : "", 5 | "css_style" : {"background_color" : "#8db3e2", 6 | "color" : "#193b64"}, 7 | "national_authority" : "UK", 8 | "rank" : 0, 9 | "active" : true}, 10 | 11 | {"classification" : "GROUP", 12 | "abbreviation" : "GR", 13 | "comment" : "", 14 | "source" : "", 15 | "css_style" : {"background_color" : "#8db3e2", 16 | "color" : "#2222dd"}, 17 | "national_authority" : "UK", 18 | "rank" : 1, 19 | "active" : true}, 20 | 21 | {"classification" : "PRIVATE", 22 | "abbreviation" : "PR", 23 | "comment" : "", 24 | "source" : "", 25 | "css_style" : {"background_color" : "#ffae37", 26 | "color" : "#a56400"}, 27 | "national_authority" : "UK", 28 | "rank" : 2, 29 | "active" : true}, 30 | 31 | {"classification" : "PERSONAL", 32 | "abbreviation" : "PE", 33 | "comment" : "", 34 | "source" : "", 35 | "css_style" : {"background_color" : "#ff7174", 36 | "color" : "#d90000"}, 37 | "national_authority" : "UK", 38 | "rank" : 3, 39 | "active" : true} 40 | ] 41 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/data/codewords.json: -------------------------------------------------------------------------------- 1 | [{"codeword" : "1", 2 | "abbreviation" : "", 3 | "comment" : "", 4 | "source" : "", 5 | "national_authority" : "", 6 | "active" : true}, 7 | 8 | {"codeword" : "2", 9 | "abbreviation" : "", 10 | "comment" : "", 11 | "source" : "", 12 | "national_authority" : "", 13 | "active" : true} 14 | ] -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/data/descriptors.json: -------------------------------------------------------------------------------- 1 | [{"descriptor" : "COMMERCIAL", 2 | "comment" : "Commercial- or market-sensitive information, including that subject to statutory or regulatory obligations, that may be damaging to HMG or to a commercial partner if improperly accessed.", 3 | "source" : "https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/251480/Government-Security-Classifications-April-2014.pdf", 4 | "national_authority" : "UK", 5 | "active" : true}, 6 | 7 | {"descriptor" : "LOCSEN", 8 | "comment" : "Sensitive information that locally engaged staff overseas cannot access.", 9 | "source" : "https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/251480/Government-Security-Classifications-April-2014.pdf", 10 | "national_authority" : "UK", 11 | "active" : true}, 12 | 13 | {"descriptor" : "PERSONAL", 14 | "comment" : "Particularly sensitive information relating to an identifiable individual, where inappropriate access could have damaging consequences. For example, where relating to investigations, vulnerable individuals, or the personal / medical records of people in sensitive posts (e.g. military, SIA).", 15 | "source" : "https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/251480/Government-Security-Classifications-April-2014.pdf", 16 | "national_authority" : "UK", 17 | "active" : true} 18 | 19 | ] 20 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/data/national_caveats.json: -------------------------------------------------------------------------------- 1 | [{"primary_name" : "MY EYES ONLY", 2 | "secondary_names" : [], 3 | "member_countries" : [], 4 | "comment" : "", 5 | "source" : "", 6 | "rank" : 4, 7 | "active" : true}] 8 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/models.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | """ 6 | Placeholder - django barfs if you don't have a models.py 7 | """ 8 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/serializers.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | import json 6 | from django.core.serializers.json import DjangoJSONEncoder 7 | from tastypie.serializers import Serializer 8 | 9 | class PrettyJSONSerializer(Serializer): 10 | json_indent = 2 11 | 12 | def to_json(self, data, options=None): 13 | options = options or {} 14 | data = self.to_simple(data, options) 15 | return json.dumps(data, cls=DjangoJSONEncoder, 16 | sort_keys=True, ensure_ascii=False, indent=self.json_indent) -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/tests/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | #from pm_tests import Test_Simple_Pm 6 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/tests/pm_tests.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | import json 6 | import urlparse 7 | 8 | from django.core import urlresolvers 9 | from django.test import client 10 | from tastypie_mongoengine import test_runner 11 | 12 | import protective_marking_app.documents as documents 13 | 14 | 15 | class TestPmBaseClass(test_runner.MongoEngineTestCase): 16 | 17 | api_name = 'v1' 18 | c = client.Client() 19 | 20 | def get_meta_and_objects(self, response): 21 | content = json.loads(response.content) 22 | return content['meta'], content['objects'] 23 | 24 | ''' User Handling Functions ''' 25 | def resourceListURI(self, resource_name): 26 | return urlresolvers.reverse('api_dispatch_list', kwargs={'api_name': self.api_name, 'resource_name': resource_name}) 27 | 28 | def resourcePK(self, resource_uri): 29 | match = urlresolvers.resolve(resource_uri) 30 | return match.kwargs['pk'] 31 | 32 | def resourceDetailURI(self, resource_name, resource_pk): 33 | return urlresolvers.reverse('api_dispatch_detail', kwargs={'api_name': self.api_name, 'resource_name': resource_name, 'pk': resource_pk}) 34 | 35 | def fullURItoAbsoluteURI(self, uri): 36 | scheme, netloc, path, query, fragment = urlparse.urlsplit(uri) 37 | return urlparse.urlunsplit((None, None, path, query, fragment)) 38 | 39 | def tearDown(self): 40 | """ All sub classes will have Ideas collection destroyed """ 41 | documents.Idea.objects.all().delete() 42 | 43 | #------------------------------------------------------------------------------------------------ 44 | ''' 45 | 46 | Insert pms into the db. 47 | 48 | Get all classifications 49 | Get all descriptors 50 | Get all national caveats 51 | Get all codewords 52 | 53 | Implement a data_level=less for just lists each of these. 54 | 55 | Classifications 56 | --------------- 57 | - get sorted by rank 58 | - Get back just abbreviations 59 | - Lookup a full classification, get back an abbreviation 60 | - Lookup an abbreviation, get back a full classification 61 | - get back just the colour? 62 | 63 | Codewords 64 | --------- 65 | - Get a list of all codewords 66 | - get a list of all abbreviated codewords 67 | - Lookup a codeword and get back an abbreviation 68 | 69 | 70 | Descriptors 71 | ----------- 72 | - Get back all descriptors 73 | - Return a plain list of descriptors 74 | 75 | 76 | National Caveats: 77 | ----------------- 78 | - Get back full detail 79 | - Get back a less list of national caveat abbreviations 80 | - Look up functionality - give an abbreviation and get back the country list 81 | - Look up functionality - give a list of nationalities and get back abbreviation? 82 | 83 | ''' 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /backend/ideaworks/protective_marking_app/views.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 3 | # Author: Rich Brantingham 4 | 5 | -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /backend/ideaworks/static/css/tastytools/api.doc.css: -------------------------------------------------------------------------------- 1 | .myButton { 2 | -moz-box-shadow:inset 0px 1px 0px 0px #ffffff; 3 | -webkit-box-shadow:inset 0px 1px 0px 0px #ffffff; 4 | box-shadow:inset 0px 1px 0px 0px #ffffff; 5 | background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #ffffff) ); 6 | background:-moz-linear-gradient( center top, #ffffff 5%, #ffffff 100% ); 7 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ffffff'); 8 | background-color:#ffffff; 9 | -moz-border-radius:27px; 10 | -webkit-border-radius:27px; 11 | border-radius:27px; 12 | border:1px solid #dcdcdc; 13 | display:inline-block; 14 | color:#e61212; 15 | font-family:Arial; 16 | font-size:15px; 17 | font-weight:bold; 18 | padding:2px 15px; 19 | text-decoration:none; 20 | text-shadow:1px 1px 0px #ffffff; 21 | }.myButton:hover { 22 | background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #ffffff) ); 23 | background:-moz-linear-gradient( center top, #ffffff 5%, #ffffff 100% ); 24 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ffffff'); 25 | background-color:#ffffff; 26 | }.myButton:active { 27 | position:relative; 28 | top:1px; 29 | } 30 | table th{ 31 | text-align: left; 32 | } 33 | 34 | #resource_list{ 35 | width: 980px; 36 | margin: 0 auto; 37 | margin-top: 50px; 38 | } 39 | .methodsBox span { 40 | background: red; 41 | color: white; 42 | font-weight: bold; 43 | padding: 2px; 44 | } 45 | .methodsBox span.allowed{ 46 | background: green; 47 | } 48 | 49 | .field_flag{ 50 | color: white; 51 | background: gold; 52 | padding: 2px; 53 | border-radius: 5px; 54 | visibility: hidden; 55 | } 56 | 57 | .resource_field span.active_flag{ 58 | visibility: visible; 59 | } 60 | 61 | .resource_btn{ 62 | cursor: pointer; 63 | } 64 | 65 | textarea { 66 | width: 800px; 67 | height: 250px; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /backend/ideaworks/static/css/tastytools/api.howto.css: -------------------------------------------------------------------------------- 1 | div.content{ 2 | width: 980px; 3 | margin: 0 auto; 4 | margin-top: 50px; 5 | } 6 | -------------------------------------------------------------------------------- /backend/ideaworks/static/css/tastytools/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Verdana,Geneva,sans-serif; 3 | font-size: 12px; 4 | } 5 | -------------------------------------------------------------------------------- /backend/ideaworks/static/img/bootstrap/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/img/bootstrap/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /backend/ideaworks/static/img/bootstrap/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/static/img/bootstrap/glyphicons-halflings.png -------------------------------------------------------------------------------- /backend/ideaworks/static/js/registration.js: -------------------------------------------------------------------------------- 1 | /* Login and Registration form functions 2 | Use for pop up of Prototypes & Description of Service text in a neat dialog box 3 | Includes a dumb down fall back for < IE6 4 | */ 5 | 6 | $(function () { 7 | 8 | var thisForm = $('form').attr('id'); 9 | //alert('This form id is : ' + thisForm); 10 | 11 | if (browser.isIE6()) { // use collapsible area for IE6 12 | $(".collapsible").on('click', function (){ 13 | $($(this).attr('href')).toggleClass('expanded'); 14 | }); 15 | } else { // use jquery-ui pop-up dialog for other browsers 16 | //alert('Not using IE6'); 17 | $( ".dialog-message" ).dialog({ 18 | modal: true, 19 | autoOpen: false, 20 | width: 400, 21 | height: 400, 22 | buttons: { 23 | Ok: function() { 24 | $(this).dialog("close"); 25 | } 26 | } 27 | }); 28 | 29 | $( ".dialog-opener" ).click(function(e) { 30 | e.preventDefault(); 31 | $( ".dialog-message" ).dialog( "open" ); 32 | }); 33 | } 34 | 35 | if (thisForm === 'login') { 36 | $('#id_username').focus(); 37 | } 38 | 39 | if (thisForm === 'registration') { 40 | $('#id_email').focus(); 41 | } 42 | 43 | }); 44 | 45 | // some checks for IE6 etc.. 46 | var browser = { 47 | isIE6: function() {if($('html').hasClass('lt-ie7')) {return true} else {return false}} 48 | } -------------------------------------------------------------------------------- /backend/ideaworks/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% load staticfiles %} 17 | 18 | 19 | 20 | {% block title_extra %} {% endblock %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% block main_block %}{% endblock main_block %} 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | {% block extra_js %}{% endblock %} 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/activate.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% block title_extra %} Registration Complete {% endblock %} 7 | 8 | {% block main_block %} 9 | 10 |
11 |
12 |

13 | Welcome. 14 |

15 |

16 | Registration Complete. Please login. 17 |

18 |
19 |
20 | {% endblock %} 21 | 22 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/activation_email.txt: -------------------------------------------------------------------------------- 1 | 3 | 4 | Here's the activation link: 5 | 6 | http://{{ site.domain }}{% url "registration_activate" activation_key=activation_key %} 7 | 8 | 9 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/activation_email_hmtl.txt: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% autoescape off %} 14 |

{{ site.name }} Sign Up

15 | 16 |

17 | Someone tried to create an account for {{ site.name }} using this email account. If you didn't request the account, just ignore this email. 18 |

19 |

20 | Click 21 | here 22 | to confirm signup to {{ site_name }}. 23 |

24 |

25 | Or copy and paste this url into your browser: http://{{ site.domain }}{% url "registration_activate" activation_key=activation_key %} 26 |

27 |

28 |

29 | {{ site.name }} team 30 |

31 | {% endautoescape %} 32 | 33 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/activation_email_subject.txt: -------------------------------------------------------------------------------- 1 | 3 | 4 | {{ site.name }} Registration -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/description_snippet.html: -------------------------------------------------------------------------------- 1 | 3 | 4 |

Description of the Service

5 |

Alpha and Beta (Public & Private)

6 |

7 | You understand and acknowledge that the Service is being provided as a "Public or Private Beta", 8 | and is made available on an "AS IS" and "AS AVAILABLE" basis for the purpose of 9 | providing Dstl with feedback on the quality and usability of the Service. 10 | The Service may contain errors or inaccuracies that could cause failures, 11 | corruption or loss of data and/or information from your device and from peripherals 12 | (including, without limitation, servers and computers) connected thereto. Dstl 13 | strongly encourages you to back-up all data and information on your device and any peripherals 14 | prior to using the Service. YOU ASSUME ALL RISKS AND ALL COSTS ASSOCIATED WITH YOUR USE OF 15 | THE SERVICE, INCLUDING, WITHOUT LIMITATION, BACK-UP EXPENSES, COSTS 16 | INCURRED FOR THE USE OF YOUR DEVICE AND PERIPHERALS, AND ANY DAMAGE TO ANY EQUIPMENT, SOFTWARE, 17 | INFORMATION OR DATA. In addition, Dstl is not obligated to provide any maintenance, technical or 18 | other support for the Service. 19 |

20 |
21 | 22 |

Changing the Service

23 |

24 | Dstl reserves the right to modify, suspend or stop the Service (or any part thereof), 25 | either temporarily or permanently, at any time or from time to time, with or without prior 26 | notice to you. Without limiting the foregoing, Dstl may provide notice of any such changes to 27 | the Service by posting them on its websites and/or via the Service. You agree that Dstl shall 28 | not be liable to you or any third party for any modification or cessation of the Service. 29 | You acknowledge that Dstl has no express or implied obligation to provide, or continue to 30 | provide, the Service, or any part thereof, now or in the future. 31 |

-------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/homepage_placeholder.html: -------------------------------------------------------------------------------- 1 | 3 | 4 |

Homepage placeholder

5 |

6 | You're seeing this because the person re-using this registration app hasn't changed the LOGIN_REDIRECT 7 | setting properly to point to the proper homepage or user profile. See configure.md for instructions. 8 |

9 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% load static %} 7 | 8 | {% block title_extra %} Login {% endblock %} 9 | 10 | {% block main_block %} 11 | 12 |
13 | 14 |
{% csrf_token %} 15 |

Please sign in

16 | 17 | {% if form.errors %} 18 |

Username or password incorrect

19 |

Please try again.

20 | {% endif %} 21 | 22 | {% autoescape off %} 23 | {{ form.username.errors }} 24 | {% endautoescape %} 25 | 26 | 27 | {{ form.username }} 28 | 29 | {% autoescape off %} 30 | {{ form.password.errors }} 31 | {% endautoescape %} 32 | 33 | 34 | {{ form.password }} 35 | 36 |
37 |
38 | 42 |
43 |
44 |
45 | Need an account? 46 |
47 | 50 | 53 | 56 | Forgotten your password? 57 |
58 |
59 |
60 |
61 | 62 | 63 |
64 |
65 | 66 | {% endblock %} 67 | 68 | {% block extra_js %} 69 | 70 | {% endblock %} 71 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/logout.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | {% load auth_tags %} 6 | 7 | {% block title_extra %} Logged Out {% endblock %} 8 | {% block main_block %} 9 | 10 |
11 |
12 |

Logged out.

13 |

You have been logged out.

14 | 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/need_an_account.html: -------------------------------------------------------------------------------- 1 | 3 | 4 |

5 | Need an account for {{ site_name }}? 6 |

7 | 8 |

9 | Click here to register. 10 |

11 | 12 | {% comment %} 13 |

14 | Send us an email and we'll get back to you shortly. 15 |

16 | {% endcomment %} 17 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_change_done_custom.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% block title_extra %} Password Changed {% endblock %} 7 | 8 | {% block main_block %} 9 | 10 |
11 |
12 |

13 | Password change successful. 14 |

15 |

16 | Your password was changed. Login again. 17 |

18 |
19 |
20 | {% endblock %} -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_change_form_custom.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% load static %} 7 | 8 | {% block title_extra %} Change Password {% endblock %} 9 | 10 | {% block main_block %} 11 | 12 |
13 | 14 |
{% csrf_token %} 15 |

Password Change

16 | {% if form.errors %} 17 |
Password Change Errors 18 |

19 | {% autoescape off %} 20 | {{ form.old_password.errors }} 21 | {% endautoescape %} 22 |

23 | {% endif %} 24 | 25 | 26 | 27 | {{ form.old_password }} 28 | 29 | {% autoescape off %} 30 | {{ form.new_password1.errors }} 31 | {% endautoescape %} 32 | 33 | {{ form.new_password1 }} 34 | 35 | {% autoescape off %} 36 | {{ form.new_password2.errors }} 37 | {% endautoescape %} 38 | 39 | {{ form.new_password2 }} 40 | 41 |

42 | 43 | 44 |
45 |
46 | 47 | 48 | {% endblock %} 49 | 50 | {% block extra_js %} 51 | 52 | {% endblock %} 53 | 54 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% block title_extra %} Password Reset Successful {% endblock %} 7 | 8 | {% block main_block %} 9 | 10 |
11 |
12 |

13 | Password reset complete. 14 |

15 |

16 | Your password has been set. 17 |

18 |

19 | Login again. 20 |

21 |
22 |
23 | {% endblock %} -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_confirm.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% block title_extra %} Reset Password {% endblock %} 7 | 8 | {% block main_block %} 9 | 10 |
11 | 12 | {% if validlink %} 13 | 14 |
{% csrf_token %} 15 |

Password Reset Confirmation

16 | 17 | {% if form.errors %} 18 |

Password Reset Errors

19 | {% endif %} 20 |
21 | 22 | {% autoescape off %} 23 | {{ form.new_password1.errors }} 24 | {% endautoescape %} 25 | 26 | {{ form.new_password1 }} 27 | 28 | {% autoescape off %} 29 | {{ form.new_password2.errors }} 30 | {% endautoescape %} 31 | 32 | {{ form.new_password2 }} 33 | 34 |

35 | 36 | 37 |
38 | 39 | {% else %} 40 | 41 |

Password Reset Unsuccessful

42 |

The password reset link was invalid, possibly because it has already been used. Please request a new password reset.

43 | 44 | {% endif %} 45 | 46 |
47 | 48 | 49 | 50 | {% endblock %} 51 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_done.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% block title_extra %} Password Reset Successful {% endblock %} 7 | 8 | {% block main_block %} 9 | 10 |
11 |
12 |

13 | Password reset successful. 14 |

15 |

16 | We've emailed you instructions for setting your password to the email address you provided. You should be receiving it shortly. 17 |

18 |

19 | Return to login screen. 20 |

21 |
22 |
23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_email.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | Someone tried to reset the password for {{ site_name }} using this email account. 5 | 6 | If you didn't request a password reset, just ignore this email or get in contact with us. 7 | 8 | Go to http://{{ site.domain }}{% url "auth_password_reset_confirm" uidb36=uid token=token %}" to change your password. 9 | 10 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_email_as_html.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% autoescape off %} 14 |

{{ site_name }} Password Reset

15 |

16 | Someone tried to reset the password for {{ site_name }} using this email account. If you didn't request a password reset, just ignore this email. 17 |

18 |

19 | Click 20 | here 21 | to change your password for {{ site_name }}. 22 |

23 | {% block reset_link %} 24 |

25 | Or copy and paste this url into your browser: {{ domain }}{% url "auth_password_reset_confirm" uidb36=uid token=token %} 26 |

27 | {% endblock %} 28 |

29 | 30 |

31 | {{ site_name }} team 32 |

33 | {% endautoescape %} 34 | 35 | 36 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_form.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% load static %} 7 | 8 | {% block title_extra %} Reset Password {% endblock %} 9 | 10 | {% block main_block %} 11 | 12 |
13 | 14 | {% if form.errors %} 15 | 16 | {% endif %} 17 | 18 |
{% csrf_token %} 19 |

Forgotten your password?

20 |

Enter your email address below, and we'll email instructions for setting a new one.

21 |
22 | 23 | {% autoescape off %} 24 | {{ form.email.errors }} 25 | {% endautoescape %} 26 | 27 | {{ form.email }} 28 | 29 |
30 | 31 | 32 |
33 |
34 | 35 | {% endblock %} 36 | 37 | {% block extra_js %} 38 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/password_reset_subject.txt: -------------------------------------------------------------------------------- 1 | 3 | 4 | {{ site_name }} Password reset -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/prototype_snippet.html: -------------------------------------------------------------------------------- 1 | 3 | 4 |

5 | {{ site_name }} is a prototype application, which means that although we strive to build great software, it is not always production grade and does not come with 24/7 support. 6 |

7 | 8 |

9 | This approach means that software is delivered and developed quickly and has much greater input from users than traditional approaches. 10 |

11 | 12 |

13 | Please read our description of service 14 | so that you understand the limitations of the application and some of the benefits of working in this way. 15 |

16 | 17 | {% comment %} 18 |

19 | As we find and fix bugs and add new features, we'll publish the changes here. 20 |

21 | {% endcomment %} 22 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/registration_auto_complete.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% block title_extra %} Registration Complete {% endblock %} 7 | 8 | {% block main_block %} 9 | 10 |
11 |
12 |

13 | Thank you! 14 |

15 |

16 | We've created an account for you. You can now use your account to log in. 17 |

18 |

19 | Visit the log in page to continue. 20 |

21 |
22 |
23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/registration_complete.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | {% load auth_tags %} 6 | {% block title_extra %} Registration Confirmation {% endblock %} 7 | 8 | {% block main_block %} 9 |
10 |
11 |

12 | Got mail? 13 |

14 |

15 | We've sent you a confirmation email. 16 |

17 |

18 | Please check your email and confirm your account by clicking on the 'confirm' button. 19 |

20 |

21 | If you don't receive an email from us, give it 5 minutes, 22 | check your junk mail and if it's still not there then please get 23 | in contact. 24 |

25 |
26 |
27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/registration_form.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% extends "base.html" %} 5 | 6 | {% load static %} 7 | 8 | {% block title_extra %} Sign up {% endblock %} 9 | 10 | {% block extra_styles %} 11 | 12 | {% endblock %} 13 | 14 | {% block main_block %} 15 | 16 |
17 |
{% csrf_token %} 18 |

Sign up

19 | 20 | {% if form.errors %} 21 |

Please take a look at the errors and try again.

22 | {% endif %} 23 | 24 | {% autoescape off %} 25 | {{ form.email.errors }} 26 | {% endautoescape %} 27 | 28 | {{ form.email }} 29 | 30 | {% autoescape off %} 31 | {{ form.password1.errors }} 32 | {% endautoescape %} 33 | 34 | {{ form.password1 }} 35 | 36 | {% autoescape off %} 37 | {{ form.password2.errors }} 38 | {% endautoescape %} 39 | 40 | {{ form.password2 }} 41 | 42 | {% autoescape off %} 43 | {{ form.first_name.errors }} 44 | {% endautoescape %} 45 | 46 | {{ form.first_name }} 47 | 48 | {% autoescape off %} 49 | {{ form.last_name.errors }} 50 | {% endautoescape %} 51 | 52 | {{ form.last_name }} 53 | 54 | {% autoescape off %} 55 | {{ form.organisation.errors }} 56 | {% endautoescape %} 57 | 58 | {{ form.organisation }} 59 | 60 | {% autoescape off %} 61 | {{ form.team.errors }} 62 | {% endautoescape %} 63 | 64 | {{ form.team }} 65 | 66 |
67 | {% autoescape off %} 68 | {{ form.tos.errors }} 69 | {% endautoescape %} 70 | 71 | 76 |
77 | 78 | 81 | 82 | 83 | 84 |
85 |
86 | 87 | {% endblock %} 88 | 89 | {% block extra_js %} 90 | 91 | {% endblock %} -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/registration_include.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 19 | 20 | 21 | {% if user.is_authenticated %} 22 |
  • 23 | 24 | 25 |
  • 26 | {% else %} 27 |
  • 28 | 29 | 30 |
  • 31 | {% endif %} 32 | -------------------------------------------------------------------------------- /backend/ideaworks/templates/registration/terms_of_service.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/templates/registration/terms_of_service.html -------------------------------------------------------------------------------- /backend/ideaworks/user_db/.placeholder_file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/backend/ideaworks/user_db/.placeholder_file -------------------------------------------------------------------------------- /dependencies_cache/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/dependencies_cache/.placeholder -------------------------------------------------------------------------------- /frontend/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/.placeholder -------------------------------------------------------------------------------- /frontend/istarter-web/README.md: -------------------------------------------------------------------------------- 1 | IdeaWorks Web Front End 2 | ====================== 3 | 4 | Installation 5 | ------------- 6 | Clone repository to a local drive, these instructions assume 7 | 8 | c:/www/ideaworks-web/ 9 | 10 | 11 | 12 | Setting up Apache to use mod proxy for Cross-Domain XMLHttpRequest Calls 13 | ======================================================================== 14 | As the API and the Web UI run on different servers (or ports) they fall foul of the same-origin policy, so a reverse proxy must be setup to allow the application to use relative paths for the Ajax requests. 15 | 16 | 17 | Local Development Setup 18 | ----------------------- 19 | **This is for local testing on a Windows PC. Change paths for Mac/Linux installations** 20 | 21 | Un-comment proxy LoadModule lines in C:\[your Apache installation path]\Apache2.2\conf\http.conf 22 | 23 | LoadModule proxy_module modules/mod_proxy.so 24 | LoadModule proxy_connect_module modules/mod_proxy_connect.so 25 | LoadModule proxy_http_module modules/mod_proxy_http.so 26 | 27 | 28 | Un-comment `Include conf/extra/httpd-vhosts.conf` line in http.conf 29 | 30 | Edit C:\[your Apache installation path]\Apache2.2\conf\extra\httpd-vhosts.conf 31 | 32 | 33 | AllowEncodedSlashes On 34 | ServerAdmin test@localhost 35 | ServerName ideaworks 36 | ServerAlias 127.0.0.1 37 | DocumentRoot "c:/www/ideaworks-web/" 38 | 39 | ProxyPass /api/ http://localhost:8000/api/ 40 | ProxyPassReverse /api/ http://localhost:8000/api/ 41 | 42 | 43 | 44 | In your hosts file (Windows - C:\Windows\System32\drivers\etc\hosts , Mac - /private/etc/hosts) add the following DNS mapping 45 | 46 | 127.0.0.1 ideaworks 47 | 48 | Restart your Apache server 49 | 50 | Start up the ideaworks API on port 8000 - $python manage.py runserver:0.0.0.0:8000 51 | 52 | You should now be able to navigate to 53 | 54 | http://ideaworks 55 | 56 | to open the web interface and 57 | 58 | http://ideaworks/api 59 | 60 | to access the API 61 | -------------------------------------------------------------------------------- /frontend/istarter-web/bootstrap/232/css/bootstrap-sortable.css: -------------------------------------------------------------------------------- 1 | table.sortable span.arrow { 2 | border-style: solid; 3 | border-width: 5px; 4 | display: block; 5 | position: absolute; 6 | top: 50%; 7 | right: 5px; 8 | font-size: 0; 9 | border-color: #ccc transparent transparent transparent; 10 | line-height: 0; 11 | height: 0; 12 | width: 0; 13 | margin-top: -2px; 14 | } 15 | 16 | table.sortable span.arrow.up { 17 | border-color: transparent transparent #ccc transparent; 18 | margin-top: -7px; 19 | } 20 | 21 | table.sortable thead th { 22 | cursor: pointer; 23 | position: relative; 24 | top: 0; 25 | left: 0; 26 | } 27 | 28 | table.sortable thead th:hover { 29 | background: #efefef; 30 | } 31 | 32 | table.sortable thead th div.mozilla { 33 | position:relative; 34 | } -------------------------------------------------------------------------------- /frontend/istarter-web/bootstrap/232/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/bootstrap/232/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /frontend/istarter-web/bootstrap/232/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/bootstrap/232/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /frontend/istarter-web/bootstrap/232/img/glyphicons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/bootstrap/232/img/glyphicons.png -------------------------------------------------------------------------------- /frontend/istarter-web/css/animations.css: -------------------------------------------------------------------------------- 1 | /* 2 | * animations css stylesheet 3 | */ 4 | 5 | /* animate ngRepeat in idea listing */ 6 | 7 | .idea-listing.ng-enter, 8 | .idea-listing.ng-leave, 9 | .idea-listing.ng-move { 10 | -webkit-transition: 0.5s linear all; 11 | -moz-transition: 0.5s linear all; 12 | -o-transition: 0.5s linear all; 13 | transition: 0.5s linear all; 14 | } 15 | 16 | .idea-listing.ng-enter, 17 | .idea-listing.ng-move { 18 | opacity: 0; 19 | height: 0; 20 | overflow: hidden; 21 | } 22 | 23 | .idea-listing.ng-move.ng-move-active, 24 | .idea-listing.ng-enter.ng-enter-active { 25 | opacity: 1; 26 | height: 120px; 27 | } 28 | 29 | .idea-listing.ng-leave { 30 | opacity: 1; 31 | overflow: hidden; 32 | } 33 | 34 | .idea-listing.ng-leave.ng-leave-active { 35 | opacity: 0; 36 | height: 0; 37 | padding-top: 0; 38 | padding-bottom: 0; 39 | } 40 | 41 | /* cross fading between routes with ngView */ 42 | 43 | .view-container { 44 | position: relative; 45 | } 46 | 47 | .view-frame.ng-enter, 48 | .view-frame.ng-leave { 49 | background: white; 50 | position: absolute; 51 | top: 0; 52 | left: 0; 53 | right: 0; 54 | } 55 | 56 | .view-frame.ng-enter { 57 | -webkit-animation: 0.5s fade-in; 58 | -moz-animation: 0.5s fade-in; 59 | -o-animation: 0.5s fade-in; 60 | animation: 0.5s fade-in; 61 | z-index: 100; 62 | } 63 | 64 | .view-frame.ng-leave { 65 | -webkit-animation: 0.5s fade-out; 66 | -moz-animation: 0.5s fade-out; 67 | -o-animation: 0.5s fade-out; 68 | animation: 0.5s fade-out; 69 | z-index: 99; 70 | } 71 | 72 | @keyframes fade-in { 73 | from { opacity: 0; } 74 | to { opacity: 1; } 75 | } 76 | @-moz-keyframes fade-in { 77 | from { opacity: 0; } 78 | to { opacity: 1; } 79 | } 80 | @-webkit-keyframes fade-in { 81 | from { opacity: 0; } 82 | to { opacity: 1; } 83 | } 84 | 85 | @keyframes fade-out { 86 | from { opacity: 1; } 87 | to { opacity: 0; } 88 | } 89 | @-moz-keyframes fade-out { 90 | from { opacity: 1; } 91 | to { opacity: 0; } 92 | } 93 | @-webkit-keyframes fade-out { 94 | from { opacity: 1; } 95 | to { opacity: 0; } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /frontend/istarter-web/css/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/css/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /frontend/istarter-web/css/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/css/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /frontend/istarter-web/css/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/css/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /frontend/istarter-web/css/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/css/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /frontend/istarter-web/css/national_caveats.json: -------------------------------------------------------------------------------- 1 | [{"primary_name" : "MY EYES ONLY", 2 | "secondary_names" : [], 3 | "member_countries" : [], 4 | "comment" : "", 5 | "source" : "", 6 | "rank" : 4, 7 | "active" : true}] 8 | -------------------------------------------------------------------------------- /frontend/istarter-web/data/ideas/idea-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "backer_count": 1, 3 | "backers": [ 4 | { 5 | "date_joined": "2013-03-13T00:09:37.385259", 6 | "email": " printouts ideas shovel deposition grooms", 7 | "first_name": " visibilities lapses", 8 | "id": 468, 9 | "last_login": "2014-01-19T00:57:13.840243", 10 | "last_name": " decision analyzer designation", 11 | "resource_uri": "/api/v1/user/468/", 12 | "username": "sack" 13 | } 14 | ], 15 | "classification": "RESTRICTED", 16 | "date_published": "2012-07-04T21:40:54.085174", 17 | "date_verified": "2012-01-05T14:58:55.544702", 18 | "description": " typewriter aggravation inches grooms navigator reveille bytes sign law addition scream transportation logs authority page graphs weapons ray abbreviations packages ignition junction rains stares gasoline break labels nothing privileges potatos", 19 | "dislikes": 0, 20 | "id": 2, 21 | "dislike_count": 4, 22 | "like_count": 14, 23 | "likes": 0, 24 | "resource_uri": "/api/v1/idea/2/", 25 | "tags": [ 26 | { 27 | "id": 19, 28 | "name": "access\n", 29 | "resource_uri": "/api/v1/tag/19/", 30 | "slug": "access" 31 | }, 32 | { 33 | "id": 26, 34 | "name": "acceptances\n", 35 | "resource_uri": "/api/v1/tag/26/", 36 | "slug": "acceptances" 37 | }, 38 | { 39 | "id": 32, 40 | "name": "abbreviation\n", 41 | "resource_uri": "/api/v1/tag/32/", 42 | "slug": "abbreviation" 43 | }, 44 | { 45 | "id": 6, 46 | "name": "abilities\n", 47 | "resource_uri": "/api/v1/tag/6/", 48 | "slug": "abilities" 49 | }, 50 | { 51 | "id": 2, 52 | "name": "xxx_test_tag", 53 | "resource_uri": "/api/v1/tag/2/", 54 | "slug": "xxx_test_tag" 55 | }, 56 | { 57 | "id": 35, 58 | "name": "accountability\n", 59 | "resource_uri": "/api/v1/tag/35/", 60 | "slug": "accountability" 61 | }, 62 | { 63 | "id": 7, 64 | "name": "acceptors\n", 65 | "resource_uri": "/api/v1/tag/7/", 66 | "slug": "acceptors" 67 | }, 68 | { 69 | "id": 22, 70 | "name": "abrasive\n", 71 | "resource_uri": "/api/v1/tag/22/", 72 | "slug": "abrasive" 73 | }, 74 | { 75 | "id": 42, 76 | "name": "accumulations\n", 77 | "resource_uri": "/api/v1/tag/42/", 78 | "slug": "accumulations" 79 | }, 80 | { 81 | "id": 3, 82 | "name": "absences\n", 83 | "resource_uri": "/api/v1/tag/3/", 84 | "slug": "absences" 85 | }, 86 | { 87 | "id": 4, 88 | "name": "acceptor\n", 89 | "resource_uri": "/api/v1/tag/4/", 90 | "slug": "acceptor" 91 | }, 92 | { 93 | "id": 5, 94 | "name": "acceleration\n", 95 | "resource_uri": "/api/v1/tag/5/", 96 | "slug": "acceleration" 97 | }, 98 | { 99 | "id": 14, 100 | "name": "accusation\n", 101 | "resource_uri": "/api/v1/tag/14/", 102 | "slug": "accusation" 103 | }, 104 | { 105 | "id": 33, 106 | "name": "absence\n", 107 | "resource_uri": "/api/v1/tag/33/", 108 | "slug": "absence" 109 | } 110 | ], 111 | "title": " twirls accesses beads", 112 | "user": "/api/v1/user/49/", 113 | "verified": true, 114 | "votes": [], 115 | "voting_ts": [] 116 | } -------------------------------------------------------------------------------- /frontend/istarter-web/data/ideas/idea-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "backer_count": 8, 3 | "backers": [ 4 | { 5 | "date_joined": "2009-04-06T21:27:53.772574", 6 | "email": " misalinement deviation", 7 | "first_name": " lanes condition trainer condi", 8 | "id": 8, 9 | "last_login": "2012-10-25T06:23:56.197872", 10 | "last_name": " multitask multiplication", 11 | "resource_uri": "/api/v1/user/8/", 12 | "username": "schedule" 13 | }, 14 | { 15 | "date_joined": "2011-09-24T16:42:57.423579", 16 | "email": " retrieval", 17 | "first_name": " ohm reach cashier", 18 | "id": 17, 19 | "last_login": "2010-08-19T00:14:11.525481", 20 | "last_name": " fireball flag", 21 | "resource_uri": "/api/v1/user/17/", 22 | "username": "debit" 23 | }, 24 | { 25 | "date_joined": "2013-05-12T16:02:22.512771", 26 | "email": " nomenclature exterior situations transmissions", 27 | "first_name": " examination", 28 | "id": 89, 29 | "last_login": "2013-02-06T22:17:05.548035", 30 | "last_name": " fronts calibers respects", 31 | "resource_uri": "/api/v1/user/89/", 32 | "username": "armament" 33 | }, 34 | { 35 | "date_joined": "2010-07-09T04:31:24.239567", 36 | "email": " saddle balloon method battles endings ax", 37 | "first_name": " trails preliminaries cases", 38 | "id": 131, 39 | "last_login": "2010-05-09T04:20:25.223848", 40 | "last_name": " south kiloliters", 41 | "resource_uri": "/api/v1/user/131/", 42 | "username": "drive" 43 | }, 44 | { 45 | "date_joined": "2014-01-28T03:18:39.002382", 46 | "email": " confinement pushup footing force", 47 | "first_name": " seeds fines vicinity", 48 | "id": 229, 49 | "last_login": "2011-12-10T18:19:36.543397", 50 | "last_name": " furs roars", 51 | "resource_uri": "/api/v1/user/229/", 52 | "username": "sex" 53 | }, 54 | { 55 | "date_joined": "2010-02-14T08:59:30.385762", 56 | "email": " method schoolroom hip", 57 | "first_name": " appraisal crewmembers", 58 | "id": 392, 59 | "last_login": "2010-10-05T05:10:12.972953", 60 | "last_name": " girl locks", 61 | "resource_uri": "/api/v1/user/392/", 62 | "username": "dwell" 63 | }, 64 | { 65 | "date_joined": "2011-05-10T06:40:02.650639", 66 | "email": " spiral transits tie", 67 | "first_name": " concentrations ambiguity male", 68 | "id": 397, 69 | "last_login": "2011-11-18T01:08:21.876465", 70 | "last_name": " churn messages", 71 | "resource_uri": "/api/v1/user/397/", 72 | "username": "rocket" 73 | }, 74 | { 75 | "date_joined": "2013-02-07T04:12:09.936969", 76 | "email": " hem laser wingnuts bullets career", 77 | "first_name": " hangar plastics", 78 | "id": 492, 79 | "last_login": "2010-11-09T02:28:57.751117", 80 | "last_name": " hum column", 81 | "resource_uri": "/api/v1/user/492/", 82 | "username": "toothpicks" 83 | } 84 | ], 85 | "classification": "UNCLASSIFIED", 86 | "date_published": "2009-03-19T12:03:56.445994", 87 | "date_verified": "2012-08-07T06:25:11.527602", 88 | "description": " ceremonies chairmen directories reveille reductions smashes percentage present blasts worth stumps items track axis margins bristle collector seconds conjunctions headings insertion auxiliaries steeple tunes cup boatswain algebra concepts offense communication west mirror fields emergency fiction wardrooms fasteners", 89 | "dislikes": 0, 90 | "id": 3, 91 | "likes": 0, 92 | "resource_uri": "/api/v1/idea/3/", 93 | "tags": [], 94 | "title": " modules circuit forecasts capital charge millimeters lash embosses magneto", 95 | "user": "/api/v1/user/35/", 96 | "verified": true, 97 | "votes": [], 98 | "voting_ts": [] 99 | } -------------------------------------------------------------------------------- /frontend/istarter-web/data/ideas/idea-4.json: -------------------------------------------------------------------------------- 1 | { 2 | "backer_count": 2, 3 | "backers": [ 4 | { 5 | "date_joined": "2012-06-22T19:17:14.077384", 6 | "email": " column war grants anticipation", 7 | "first_name": " aprons breakdowns", 8 | "id": 91, 9 | "last_login": "2010-06-11T10:56:34.247893", 10 | "last_name": " altitude", 11 | "resource_uri": "/api/v1/user/91/", 12 | "username": "maneuvers" 13 | }, 14 | { 15 | "date_joined": "2010-02-23T00:45:06.704962", 16 | "email": " store monoliths liberty grooves", 17 | "first_name": " clap floors", 18 | "id": 493, 19 | "last_login": "2010-01-20T03:24:24.066098", 20 | "last_name": " diagnosis fuels", 21 | "resource_uri": "/api/v1/user/493/", 22 | "username": "automation" 23 | } 24 | ], 25 | "classification": "CONFIDENTIAL", 26 | "date_published": "2010-10-05T21:59:36.172752", 27 | "date_verified": "2011-11-03T09:43:31.018729", 28 | "description": " spills fact core accidents drydock prepositions distributor satellites execution dwell distress volume slits country card keels ounces misalignment cements saddle responses composition farms overcurrents codes rumble", 29 | "dislikes": 0, 30 | "id": 4, 31 | "likes": 0, 32 | "resource_uri": "/api/v1/idea/4/", 33 | "tags": [ 34 | { 35 | "id": 2, 36 | "name": "xxx_test_tag", 37 | "resource_uri": "/api/v1/tag/2/", 38 | "slug": "xxx_test_tag" 39 | }, 40 | { 41 | "id": 8, 42 | "name": "abuse\n", 43 | "resource_uri": "/api/v1/tag/8/", 44 | "slug": "abuse" 45 | } 46 | ], 47 | "title": " hopes river alibis services diagonals parcels laugh nations automobiles impact vapor measures question", 48 | "user": "/api/v1/user/307/", 49 | "verified": true, 50 | "votes": [], 51 | "voting_ts": [] 52 | } -------------------------------------------------------------------------------- /frontend/istarter-web/data/protective_marking/classifications.json: -------------------------------------------------------------------------------- 1 | [{"classification" : "PUBLIC", 2 | "abbreviation" : "PU", 3 | "comment" : "", 4 | "source" : "", 5 | "css_style" : {"background_color" : "#8db3e2", 6 | "color" : "#193b64"}, 7 | "national_authority" : "UK", 8 | "rank" : 0, 9 | "active" : true}, 10 | 11 | {"classification" : "GROUP", 12 | "abbreviation" : "GR", 13 | "comment" : "", 14 | "source" : "", 15 | "css_style" : {"background_color" : "#8db3e2", 16 | "color" : "#2222dd"}, 17 | "national_authority" : "UK", 18 | "rank" : 1, 19 | "active" : true}, 20 | 21 | {"classification" : "PRIVATE", 22 | "abbreviation" : "PR", 23 | "comment" : "", 24 | "source" : "", 25 | "css_style" : {"background_color" : "#ffae37", 26 | "color" : "#a56400"}, 27 | "national_authority" : "UK", 28 | "rank" : 2, 29 | "active" : true}, 30 | 31 | {"classification" : "PERSONAL", 32 | "abbreviation" : "PE", 33 | "comment" : "", 34 | "source" : "", 35 | "css_style" : {"background_color" : "#ff7174", 36 | "color" : "#d90000"}, 37 | "national_authority" : "UK", 38 | "rank" : 3, 39 | "active" : true} 40 | ] 41 | -------------------------------------------------------------------------------- /frontend/istarter-web/data/protective_marking/codewords.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "codeword" : "BANANA1", 3 | "abbreviation" : "B1", 4 | "comment" : "information about bananas", 5 | "source" : "", 6 | "national_authority" : "UK", 7 | "active" : true 8 | }, { 9 | "codeword" : "BANANA2", 10 | "abbreviation" : "B3", 11 | "comment" : "sensitive information about bananas", 12 | "source" : "", 13 | "national_authority" : "UK", 14 | "active" : true 15 | }, { 16 | "codeword" : "APPLE", 17 | "abbreviation" : "A1", 18 | "comment" : "information about apples", 19 | "source" : "", 20 | "national_authority" : "UK", 21 | "active" : true 22 | },{ 23 | "codeword" : "APPLE2", 24 | "abbreviation" : "A2", 25 | "comment" : "information about apples", 26 | "source" : "", 27 | "national_authority" : "UK", 28 | "active" : true 29 | }, { 30 | "codeword" : "PEAR", 31 | "abbreviation" : "P1", 32 | "comment" : "information about pears", 33 | "source" : "", 34 | "national_authority" : "UK", 35 | "active" : true 36 | }, { 37 | "codeword" : "ORANGE", 38 | "abbreviation" : "O1", 39 | "comment" : "information about oranges", 40 | "source" : "", 41 | "national_authority" : "UK", 42 | "active" : true 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /frontend/istarter-web/data/protective_marking/descriptors.json: -------------------------------------------------------------------------------- 1 | [{"descriptor" : "COMMERCIAL", 2 | "comment" : "Commercial- or market-sensitive information, including that subject to statutory or regulatory obligations, that may be damaging to HMG or to a commercial partner if improperly accessed.", 3 | "source" : "https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/251480/Government-Security-Classifications-April-2014.pdf", 4 | "national_authority" : "UK", 5 | "active" : true}, 6 | 7 | {"descriptor" : "LOCSEN", 8 | "comment" : "Sensitive information that locally engaged staff overseas cannot access.", 9 | "source" : "https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/251480/Government-Security-Classifications-April-2014.pdf", 10 | "national_authority" : "UK", 11 | "active" : true}, 12 | 13 | {"descriptor" : "PERSONAL", 14 | "comment" : "Particularly sensitive information relating to an identifiable individual, where inappropriate access could have damaging consequences. For example, where relating to investigations, vulnerable individuals, or the personal / medical records of people in sensitive posts (e.g. military, SIA).", 15 | "source" : "https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/251480/Government-Security-Classifications-April-2014.pdf", 16 | "national_authority" : "UK", 17 | "active" : true} 18 | 19 | ] 20 | -------------------------------------------------------------------------------- /frontend/istarter-web/data/protective_marking/national_caveats.json: -------------------------------------------------------------------------------- 1 | [{"primary_name" : "MY EYES ONLY", 2 | "secondary_names" : [], 3 | "member_countries" : [], 4 | "comment" : "", 5 | "source" : "", 6 | "rank" : 4, 7 | "active" : true}] 8 | -------------------------------------------------------------------------------- /frontend/istarter-web/data/site_content/types.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage" : { 3 | "key" : "homepage", 4 | "label" : "Home page", 5 | "navtext" : "Home pages" 6 | }, 7 | "faq" : { 8 | "key" : "faq", 9 | "label" : "FAQ", 10 | "navtext" : "FAQs" 11 | }, 12 | "document" : { 13 | "key" : "document", 14 | "label" : "Document", 15 | "navtext" : "Documents" 16 | }, 17 | "help" : { 18 | "key" : "help", 19 | "label" : "Help", 20 | "navtext" : "Help pages" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/istarter-web/data/tags/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "limit": 20, 4 | "next": "/api/v1/tag/?limit=20&offset=20", 5 | "offset": 0, 6 | "previous": null, 7 | "total_count": 234 8 | }, 9 | "objects": [ 10 | { 11 | "count": 4, 12 | "text": "steps" 13 | }, 14 | { 15 | "count": 3, 16 | "text": "acquittals" 17 | }, 18 | { 19 | "count": 3, 20 | "text": "shell" 21 | }, 22 | { 23 | "count": 3, 24 | "text": "pats" 25 | }, 26 | { 27 | "count": 3, 28 | "text": "democracy" 29 | }, 30 | { 31 | "count": 3, 32 | "text": "servo" 33 | }, 34 | { 35 | "count": 3, 36 | "text": "swivel" 37 | }, 38 | { 39 | "count": 3, 40 | "text": "rules" 41 | }, 42 | { 43 | "count": 3, 44 | "text": "apprenticeships" 45 | }, 46 | { 47 | "count": 3, 48 | "text": "leave" 49 | }, 50 | { 51 | "count": 3, 52 | "text": "measurements" 53 | }, 54 | { 55 | "count": 3, 56 | "text": "tag" 57 | }, 58 | { 59 | "count": 3, 60 | "text": "clumps" 61 | }, 62 | { 63 | "count": 2, 64 | "text": "item" 65 | }, 66 | { 67 | "count": 2, 68 | "text": "designators" 69 | }, 70 | { 71 | "count": 2, 72 | "text": "discharge" 73 | }, 74 | { 75 | "count": 2, 76 | "text": "mines" 77 | }, 78 | { 79 | "count": 2, 80 | "text": "laws" 81 | }, 82 | { 83 | "count": 2, 84 | "text": "equivalents" 85 | }, 86 | { 87 | "count": 2, 88 | "text": "wills" 89 | } 90 | ] 91 | } -------------------------------------------------------------------------------- /frontend/istarter-web/images/iStarter Logo greyscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/iStarter Logo greyscale.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/iStarter Logo long tagline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/iStarter Logo long tagline.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/iStarter Logo long.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/iStarter Logo long.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/iStarter Logo tranparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/iStarter Logo tranparent.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/iStarter Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/iStarter Logo.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/istarter-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/istarter-large.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/istarter-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/istarter-logo.png -------------------------------------------------------------------------------- /frontend/istarter-web/images/mongoDB-logo-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/frontend/istarter-web/images/mongoDB-logo-40.png -------------------------------------------------------------------------------- /frontend/istarter-web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | IdeaWorks 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
    79 | 80 |
    81 |
    82 |
    83 | 84 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /frontend/istarter-web/js/animations.js: -------------------------------------------------------------------------------- 1 | /* (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK */ 2 | 3 | 'use strict'; 4 | 5 | /************************************************************************ 6 | * Animations 7 | * ideaworks.ngAnimations 8 | *************************************************************************/ 9 | 10 | 11 | ideaworks.ngAnimations = angular.module('ideaworks.ngAnimations', ['ngAnimate']); 12 | 13 | /* 14 | ideaworks.ngAnimations.animation('.idea', function() { 15 | 16 | var animateUp = function(element, className, done) { 17 | if(className != 'active') { 18 | return; 19 | } 20 | element.css({ 21 | position: 'absolute', 22 | top: 500, 23 | left: 0, 24 | display: 'block' 25 | }); 26 | 27 | jQuery(element).animate({ 28 | top: 0 29 | }, done); 30 | 31 | return function(cancel) { 32 | if(cancel) { 33 | element.stop(); 34 | } 35 | }; 36 | } 37 | 38 | var animateDown = function(element, className, done) { 39 | if(className != 'active') { 40 | return; 41 | } 42 | element.css({ 43 | position: 'absolute', 44 | left: 0, 45 | top: 0 46 | }); 47 | 48 | jQuery(element).animate({ 49 | top: -500 50 | }, done); 51 | 52 | return function(cancel) { 53 | if(cancel) { 54 | element.stop(); 55 | } 56 | }; 57 | } 58 | 59 | return { 60 | addClass: animateUp, 61 | removeClass: animateDown 62 | }; 63 | }); 64 | 65 | 66 | */ -------------------------------------------------------------------------------- /frontend/istarter-web/js/filters.js: -------------------------------------------------------------------------------- 1 | /* (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK */ 2 | 3 | 'use strict'; 4 | 5 | /************************************************************************ 6 | * Filters 7 | * ideaworks.ngFilters 8 | *************************************************************************/ 9 | 10 | ideaworks.ngFilters = angular.module('ideaworks.ngFilters', []); 11 | 12 | /************************************************************************ 13 | * truncate 14 | * usage; 15 | * {{ textToTruncate | truncate:20 }} 16 | *************************************************************************/ 17 | ideaworks.ngFilters.filter('truncate', function () { 18 | return function (input, chars) { 19 | 20 | if (isNaN(chars)) return input; 21 | if (chars <=0) return ''; 22 | if (input && input.length > chars) { 23 | // truncate the text 24 | return input.substring(0, chars) + ' . . .'; 25 | } else { 26 | // don't truncate the text 27 | return input 28 | } 29 | } 30 | 31 | }); 32 | 33 | /************************************************************************ 34 | * checkmark - use to create a tick or cross depending on input (true/false) 35 | * usage; 36 | * {{ text | checkmark }} 37 | *************************************************************************/ 38 | ideaworks.ngFilters.filter('checkmark', function() { 39 | return function(input) { 40 | if (input) { 41 | return input ? '\u2713' : '\u2718'; 42 | } else { 43 | return input; 44 | } 45 | }; 46 | }); 47 | 48 | /************************************************************************ 49 | * hyphenate - use to create classnames etc... 50 | * usage; 51 | * {{ textToHyphenate | hyphenate }} 52 | *************************************************************************/ 53 | ideaworks.ngFilters.filter('hyphenate', function() { 54 | return function (input) { 55 | if (input) { 56 | return input.replace(/ +/g, '-'); 57 | } else { 58 | return input; 59 | } 60 | }; 61 | }); -------------------------------------------------------------------------------- /frontend/istarter-web/js/lib/angular/angular-bootstrap-select.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-bootstrap-select.extra', []) 2 | .directive('toggle', function () { 3 | return { 4 | restrict: 'A', 5 | link: function (scope, element, attrs) { 6 | var target = element.parent(); 7 | 8 | element.bind('click', function () { 9 | target.toggleClass('open') 10 | }); 11 | 12 | element.next().find('li').bind('click', function () { 13 | target.toggleClass('open') 14 | }) 15 | } 16 | }; 17 | }); 18 | 19 | angular.module('angular-bootstrap-select', []) 20 | .directive('selectpicker', function () { 21 | return { 22 | restrict: 'CA', 23 | require: '?ngModel', 24 | compile: function (tElement, tAttrs, transclude) { 25 | tElement.selectpicker(); 26 | return function (scope, element, attrs, ngModel) { 27 | ngModel.$render = function() { 28 | element.val(ngModel.$viewValue || '').selectpicker('render'); 29 | }; 30 | ngModel.$viewValue = element.val(); 31 | }; 32 | } 33 | }; 34 | }); 35 | -------------------------------------------------------------------------------- /frontend/istarter-web/js/lib/angular/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.3.0-beta.6 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)d=c[a],f.isString(d)||(d=""+d,c[a]=d),d!==g[a]&&(b.cookies(a,d),e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?delete c[a]:c[a]=d[a])});return c}]).factory("$cookieStore", 7 | ["$cookies",function(e){return{get:function(b){return(b=e[b])?f.fromJson(b):b},put:function(b,c){e[b]=f.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular); 8 | //# sourceMappingURL=angular-cookies.min.js.map 9 | -------------------------------------------------------------------------------- /frontend/istarter-web/js/lib/angular/angular-loader.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.3.0-beta.6 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.3.0-beta.6/"+(a?a+"/":"")+c;for(b=1;be&&s/dm&&10>p|| 8 | (p>m?(e=!1,c.cancel&&c.cancel(a)):(a.preventDefault(),c.move&&c.move(n,a)))}});a.on("touchend mouseup",function(a){e&&(e=!1,c.end&&c.end(f(a),a))})}}}]);r.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(a){a.shift();return a}])}]);r.directive("ngClick",["$parse","$timeout","$rootElement",function(f,a,c){function m(a,b,c){for(var d=0;dg)){var b= 9 | a.touches&&a.touches.length?a.touches:[a],c=b[0].clientX,b=b[0].clientY;1>c&&1>b||k&&k[0]===c&&k[1]===b||(k&&(k=null),"label"===a.target.tagName.toLowerCase()&&(k=[c,b]),m(l,c,b)||(a.stopPropagation(),a.preventDefault(),a.target&&a.target.blur()))}}function q(c){c=c.touches&&c.touches.length?c.touches:[c];var b=c[0].clientX,e=c[0].clientY;l.push(b,e);a(function(){for(var a=0;ag&&12>s)&&(l||(c[0].addEventListener("click",p,!0),c[0].addEventListener("touchstart",q,!0),l=[]),n=Date.now(),m(l,f,h),t&&t.blur(),w.isDefined(e.disabled)&&!1!==e.disabled||b.triggerHandler("click",[a]));d()});b.onclick=function(a){};b.on("click",function(b,c){a.$apply(function(){g(a,{$event:c||b})})});b.on("mousedown",function(a){b.addClass(h)});b.on("mousemove mouseup",function(a){b.removeClass(h)})}}]); 12 | u("ngSwipeLeft",-1,"swipeleft");u("ngSwipeRight",1,"swiperight")})(window,window.angular); 13 | //# sourceMappingURL=angular-touch.min.js.map 14 | -------------------------------------------------------------------------------- /frontend/istarter-web/js/lib/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); 8 | if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d 2 |

    About IdeaWorks (prototype)

    3 |
    4 | 5 |

    Aims

    6 |

    7 | The IdeaWorks web application is designed to encourage staff to share, contribute and collaborate on ideas. 8 |

    9 | The application will provide a means by which those with resources (manpower, equipment, development resources etc.) can support ('back') the ideas. In doing so, the application supports the existing requirements management process by de-risking the longer term acquisition and providing a broader, systematic and quantitative approach to requirements capture. 10 |

    11 |
    12 |

    Contacts

    13 |

    14 | For further information please contact; 15 |

    16 | Rich Brantingham
    17 | Multi-Source Intelligence Exploitation Team
    18 | e: rbrantingham@dstl.gov.uk
    19 | t: +44(0)1980 61 6409
    20 |
    21 | Or
    22 |
    23 | Russell King
    24 | Multi-Source Intelligence Exploitation Team
    25 | e: reking@dstl.gov.uk
    26 | t: +44(0)1980 61 6253
    27 |
    28 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/docs/description-of-service.html: -------------------------------------------------------------------------------- 1 |

    2 |

    Description of the Service

    3 |
    4 |

    Alpha and Beta Prototype Applications

    5 |

    6 | You understand and acknowledge that the Service is being provided as a "Public or Private Beta", and is made available on an "AS IS" and "AS AVAILABLE" basis for the purpose of providing Dstl with feedback on the quality and usability of the Service. The Service may contain errors or inaccuracies that could cause failures, corruption or loss of data and/or information from your device and from peripherals (including, without limitation, servers and computers) connected thereto. Dstl strongly encourages you to back-up all data and information on your device and any peripherals prior to using the Service. YOU ASSUME ALL RISKS AND ALL COSTS ASSOCIATED WITH YOUR USE OF THE SERVICE, INCLUDING, WITHOUT LIMITATION, BACK-UP EXPENSES, COSTS INCURRED FOR THE USE OF YOUR DEVICE AND PERIPHERALS, AND ANY DAMAGE TO ANY EQUIPMENT, SOFTWARE, INFORMATION OR DATA. In addition, Dstl is not obligated to provide any maintenance, technical or other support for the Service. 7 |

    8 |
    9 |

    Changing the Service

    10 |

    11 | Dstl reserves the right to modify, suspend or stop the Service (or any part thereof), either temporarily or permanently, at any time or from time to time, with or without prior notice to you. Without limiting the foregoing, Dstl may provide notice of any such changes to the Service by posting them on its websites and/or via the Service. You agree that Dstl shall not be liable to you or any third party for any modification or cessation of the Service. You acknowledge that Dstl has no express or implied obligation to provide, or continue to provide, the Service, or any part thereof, now or in the future. 12 |

    13 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/feedback/view-sidebar.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 |
    5 | 6 | 7 |
    8 |
    9 | 10 |
    11 | 13 |
    14 | 15 | 18 |
    19 |
    20 | 21 | 22 |
    23 | 24 | 30 |
    31 | 32 |
    33 |
    34 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/feedback/view.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 |
    6 | 7 |
    8 | 9 | 10 |
    11 |
    Viewing - Feedback
    12 | 13 | 20 | 21 |
    22 | 23 |
    24 |
    25 | 26 | 27 | 37 | 38 | 39 |
    40 | 41 |
    42 | 43 | 44 |
    45 | {{feedback.contributor_name}} 46 | {{feedback.informal_created}} 47 |
    48 | 49 | 50 |
    51 |
    52 | 53 |
    54 |
    55 |
    56 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/ideas/likes-bar.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 | 7 | 8 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/ideas/popups.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/ideas/view/all.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 |
    4 | 5 | 10 | 11 |
    12 | 13 | 30 | 31 | 32 | 33 |
    34 |
    35 |
    36 | 37 | 38 | 42 | 43 |
    LOADING Please wait....{{viewIsloading}} 44 |
    45 |
    46 | 47 |
    48 | 49 |
    50 |
    {{idea.title}}

    51 | {{idea.description | truncate:330}}

    {{idea.informal_created}} 52 | 53 |
    54 |
    55 | 56 |
    57 | 58 | 59 |
    60 |
    {{idea.comment_count}}
    61 |
    62 |
    63 |
    64 | 65 |
    66 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/ideas/view/grid.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 |
    6 | 7 |
    8 | 9 | 10 |
    11 | 12 | 13 |
    14 | 15 |
    16 |
    17 | 18 | 19 | 20 | 23 | 24 | 25 |
    26 | 27 |
    28 | 29 | 30 |
    31 | {{idea.contributor_name}} 32 | {{idea.informal_created}} 33 |
    34 | 35 | 36 |
    {{idea.description_snippet | truncate: 120}}
    37 | 38 | 39 |
    40 | 41 |
    42 | 43 | 44 | 49 | 50 | 51 |
    52 | 53 | 61 |
    62 | 63 |
    64 |
    65 |
    66 |
    67 |
    68 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/ideas/view/list.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 |
    6 | 7 |
    8 | 9 | 10 |
    11 | 12 | 13 |
    14 | 15 |
    16 | 17 |
    18 |
    19 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/ideas/view/switch-layout.html: -------------------------------------------------------------------------------- 1 |
    Viewing - Ideas
    2 |
    Viewing - My Ideas
    3 | 4 |
    5 | View as 6 | summary 7 | grid 8 | list 9 | 10 |
    11 | 12 | 13 | 14 | 22 | 23 | 30 | 31 |
    32 |
    Loading. Please wait.... 33 |
    34 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/logged-out.html: -------------------------------------------------------------------------------- 1 |

    Logged out

    2 |

    You have been logged out.

    3 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/modals/dislike.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/modals/like.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/not-found.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Not found

    3 |

    4 | {{errorUrl}} 5 |

    Sorry this page can not be found. It may have been deleted

    6 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/projects/view/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 |
    5 | 6 | 7 |
    8 |
    9 | 10 |
    11 | 13 |
    14 | 15 | 18 |
    19 |
    20 | 21 |
    22 | 24 |
    25 | 26 | 29 |
    30 |
    31 | 32 | 33 | 34 |
    35 | 36 |
    37 | 38 | 39 |
    40 | 41 | 48 |
    49 | 50 |
    51 |
    52 | 53 |
    54 | 55 | 56 |
    57 |
    58 |   59 |
    60 | 61 | 62 |
    63 |
    64 |
    65 |
    66 | 67 | 68 | 69 | 70 | Click a tag to filter projects 71 | Select tags and click here to filter 72 | 73 |
    74 |
    75 | 76 | 77 | 78 |
    79 | 80 |
    81 |
    82 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/projects/view/summary.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 |
    6 | 7 |
    8 | 9 | 10 |
    11 | 12 | 13 |
    14 | 15 |
    16 |
    17 | 18 |
    19 | 20 | 21 | 31 | 32 | 33 |
    34 | 35 |
    36 | 37 | 38 | {{project.contributor_name}} 39 | {{project.informal_created}} 40 | 41 | 42 |
    {{project.description_snippet}}
    43 | 44 | 45 |
    46 | 47 |
    48 | 49 |
    50 | 51 |
    52 | 53 |
    54 | 55 | 56 | 61 |
    62 |
    63 | 64 | 65 |
    66 | 67 |
    68 |
    69 |
    70 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/projects/view/switch-layout.html: -------------------------------------------------------------------------------- 1 |
    Viewing - Projects
    2 |
    Viewing - My Projects
    3 | 4 |
    5 | View as 6 | summary 7 | grid 8 | list 9 | 10 |
    11 | 12 | 13 | 14 | 22 | 23 | 30 | 31 |
    32 |
    Loading. Please wait.... 33 |
    34 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/site-content/index.html: -------------------------------------------------------------------------------- 1 |
    Loading. Please wait.... 2 |
    3 |
    4 | 5 |
    6 | 7 |
    {{contentlabel}} index page not found
    8 | 9 |

    The site administrator has not created an index page.

    10 | 11 |
    12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/istarter-web/templates/site-content/view.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 |
    6 | 7 |
    8 | 9 |
    10 |
    11 | 12 | 13 | 23 | 24 | 25 |
    26 | 27 |
    28 | 29 |
    Type : {{siteContentTypes[content.type].label}} (index page)
    30 | 31 |
    32 | {{content.contributor_name}} 33 | {{content.informal_created}} 34 |
    35 | 36 |
    {{content.summary}}
    37 |
    38 |
    39 | 40 |
    41 |
    42 |
    43 |
    -------------------------------------------------------------------------------- /frontend/istarter-web/templates/tags.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    All Tags ({{tags.meta.total_count}})

    4 | 21 |
    22 |
    23 | 24 | {{tag.text}} {{tag.count}} 25 | 26 |
    27 |
    28 |
    29 | 30 | 31 | -------------------------------------------------------------------------------- /readme_images/add_a_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/readme_images/add_a_comment.png -------------------------------------------------------------------------------- /readme_images/create_an_idea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/readme_images/create_an_idea.png -------------------------------------------------------------------------------- /readme_images/view_an_idea_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/readme_images/view_an_idea_details.png -------------------------------------------------------------------------------- /readme_images/view_ideas_summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dstl/ideaworks/11e438c31dade710898e3bec724c7c28ec3ff69f/readme_images/view_ideas_summary.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # (c) Crown Copyright 2011 Defence Science and Technology Laboratory UK 2 | # Author: Rich Brantingham 3 | 4 | # (c) Crown Copyright 2014 Defence Science and Technology Laboratory UK 5 | # Author: Rich Brantingham 6 | 7 | # Basic requirements 8 | docutils==0.11 9 | biplist==0.6 10 | defusedxml==0.4.1 11 | Django==1.5.11 12 | six==1.5.2 13 | wsgiref==0.1.2 14 | python-dateutil==2.2 15 | 16 | # For py3 support - tests will error without this 17 | # https://github.com/MongoEngine/mongoengine/issues/209 18 | nose==1.3.0 19 | 20 | 21 | # For the API 22 | #django-tastypie 23 | PyYAML==3.10 24 | lxml==3.3.2 25 | python-mimeparse==0.1.4 26 | 27 | 28 | # Getting it direct from source because the pypi version isn't as current and has some issues. 29 | #git+https://github.com/toastdriven/django-tastypie.git 30 | 31 | # Mongo specific 32 | pymongo==2.6.3 33 | mongoengine==0.8.7 34 | django-tastypie-mongoengine==0.4.5 35 | 36 | 37 | # Authentication 38 | django-profiles==0.2 39 | django-registration==1.0 40 | django-registration-email==0.7.1 41 | 42 | # For testing only 43 | requests==2.2.1 44 | 45 | # For generating docs 46 | # git+git://github.com/juanique/django-tastytools.git#egg=django_tastytools-dev 47 | # The following was useful: https://tastytools.readthedocs.org/en/latest/tutorial.html#installation 48 | 49 | #///////////////////////////////////////////////////////////////////////////////////////////////////// 50 | # 51 | # Using a 2 stage approach - download and then install - useful for offline 52 | # pip install --download -r requirements.txt 53 | # pip install --no-index --find-links=[file://] -r requirements.txt 54 | # 55 | #///////////////////////////////////////////////////////////////////////////////////////////////////// 56 | --------------------------------------------------------------------------------