{"id":17222946,"url":"https://github.com/cheind/gae-progress","last_synced_at":"2025-03-25T16:22:28.349Z","repository":{"id":66174974,"uuid":"49085374","full_name":"cheind/gae-progress","owner":"cheind","description":"Google App Engine project for progress management","archived":false,"fork":false,"pushed_at":"2016-01-19T16:27:13.000Z","size":6598,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-30T14:25:33.394Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cheind.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-05T18:45:36.000Z","updated_at":"2016-01-15T09:49:11.000Z","dependencies_parsed_at":"2023-02-20T23:15:57.875Z","dependency_job_id":null,"html_url":"https://github.com/cheind/gae-progress","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Fgae-progress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Fgae-progress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Fgae-progress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Fgae-progress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cheind","download_url":"https://codeload.github.com/cheind/gae-progress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245496418,"owners_count":20624885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T04:06:46.949Z","updated_at":"2025-03-25T16:22:28.316Z","avatar_url":"https://github.com/cheind.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## What it does\n**gae-progress** is a [Google App Engine](https://cloud.google.com/appengine/) (GAE) project managing arbitrary progresses. It is meant for people getting started with GAE and [PaaS](https://en.wikipedia.org/wiki/Platform_as_a_service).\n![Web Client](etc/webfront.png)\n\nTest the [live demo](https://progress-1181.appspot.com).\n\n## What's in it\n\nThe features at a glance:\n  - a RESTful web service\n    - to create, update, delete and query progresses,\n    - implemented using [Google Endpoints API](https://cloud.google.com/appengine/docs/python/endpoints/),\n    - supporting user authentication / authorization using [OpenID Connect](https://developers.google.com/identity/protocols/OpenIDConnect) or by API keys.\n  - Web app build with [AngularJS](https://angularjs.org/).\n  - A collection of clients written in (Python, Javascript, Java and C++).\n\n## Structure\n\nThe project is structured as follows:\n  - the `backend` directory contains files making up the application that runs on GAE. It consists of\n    - `backend/progress` a RESTful service for managing progresses based [Google Endpoints API](https://cloud.google.com/appengine/docs/python/endpoints/)\n    - `backend/www` a web app to access and manage progresses\n  - the `clients` directory contains additional clients utilizing the progress API.\n\n## Getting started\n\nA couple of steps are required in order to run this backend service under your Google account.\n\n#### Create a new GAE project\n\nOpen the [Google Developer Console](https://console.developers.google.com), click on *Create a project* and write down its `Project-ID`.\n\n#### Set up credentials\n\nNext, you need to create new credentials for OAuth (OpenID connect) support. This will be needed so users can authenticate with our progress API via the web app. Here are the steps.\n\n  1. In the developer console open *API Manager/Credentials* and create a new *OAuth client ID* credential.\n  1. Select *Web application*.\n  1. In *Authorized Javascript Origins* add `http://localhost:8080` and `https://Project-ID.appspot.com`.\n  1. In *Authorized redirect URIs* add `http://localhost:8080/oauth2callback` and `https://Project-ID.appspot.com/oauth2callback`.\n  1. Write down the generated `Client-ID`.\n  1. In *API Manager/Credentials* create a *OAuth Consent Screen*. Default values are ok.\n\nIf you are feeling lost, more info on this process can be found [here](https://cloud.google.com/appengine/docs/python/endpoints/auth#Python_Creating_OAuth_20_client_IDs).\n\n#### Get the source code\nFork or download a [release](/releases) of this repository. Update the source using your `Client-ID` and `Project-ID` values.\n\n  - In `backend/app.yaml` update `application: Project-ID`\n  - In `backend/progress/constants.py` update `WEB_CLIENT_ID = 'Client-ID'`\n  - In `backend/www/js/app.js` update `CLIENT_ID: 'Client-ID'`\n\n#### Start the development server\n\nInstall the [Google App Engine SDK for Python](https://cloud.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python). At the time of writing the 1.9.30 was the most recent version. Navigate to the `backend` directory and run\n\n```\n\u003e devappserver.py .\n```\n\nfrom the command line. If all goes well you should be able to access `http://localhost:8080` and see welcome message similar to:\n\n![Web Client](etc/welcome.png)\n\nIf you cannot access the service, make you don't spot any errors in the console log. If you have multiple GAE instances running locally, check which port was bound by the server. Browsing the output you should see something along the lines of:\n```\nStarting module \"default\" running at: http://localhost:8080\n```\n\n## API design\n\nOnce the backend server is up and running you can explore the API using Google API Explorer. It's accessible from `http://localhost:8080/_ah/api/explorer`. Alternatively you can browse the [live API](https://progress-1181.appspot.com/_ah/api/explorer).\n\n\n#### Methods\nThe `progressApi` provides the following methods\n  - `create`, `update`, `delete` for modifying progresses.\n  - `list` for querying progresses.\n  - `userProfile`, `generateNewApiKey` for managing user related properties.\n\n#### Entities\n\nFrom a database perspective `progressApi` modifies two kinds of entities: `User` and `Progress`. The `User` entity holds sensitive user information such as E-Mail address and API key.\n```python\nclass User(ndb.Model):\n    email = ndb.StringProperty()\n    apikey = ndb.StringProperty()\n```\n\nThe `Progress` entity stores information on individual progresses.\n```python\nclass Progress(ndb.Model):\n    title = ndb.StringProperty()\n    description = ndb.StringProperty()\n    progress = ndb.FloatProperty(default=0.0)\n    created = ndb.DateTimeProperty(auto_now_add=True)\n    lastUpdated = ndb.DateTimeProperty(auto_now=True)\n```\n\n#### Keys\n\nWe will use the MD5 hashed E-Mail address as the key for `User`. Although this bears the small chance of generating duplicate keys, it provides some benefits when dealing with API keys as we will see in the [Authentication](#Authentication) section. Also note, the OpenID Connect protocol provides a unique user id that could be used instead.\n\nWe let the datastore automatically generate unique ids used as keys for `Progress` entities. As progresses are created by specific users, we require that a `Progress` key needs to have a `User` key as parent (see [ancestor relationship](https://cloud.google.com/appengine/docs/python/ndb/entities) for more info). `Progress` IDs generated by the datastore will only be unique in the context of a parent `User` key.\n\n#### Messages\nEach method provided by `progressApi` requires request and response messages. In Google Endpoints these are modelled using [Google Protocol Buffers](https://developers.google.com/protocol-buffers/), a framework that provides flexible message serialization in multiple languages. All messages can be found in [models.py](backend/progress/models.py).\n\n\n#### Authentication \u003ca name=\"Authentication\"\u003e\u003c/a\u003e\n\n`progressApi` supports OpenID Connect for user authentication. Once a user authenticates, the user is fetched from the known `User` entities. If the user is not found in the datastore, a new `User` will be created on the fly. This way, sign up and sign in are actually one step.\n\nThere are a number of steps involved in authentication via OpenID Connect, a fact that could throw of users from using your API as developing clients becomes too complex. As a consequence each `User` is also assigned an API key that can be used as an alternative way of authentication.\n\nThe API key is randomly generated id that can be passed along with each `progressApi` request. When the backend API detects that an API key is present on a request, it looks up the corresponding `User` and verifies that the two API keys match.\n\nThe API key is a string assembled from two parts: `User-UUID`. The former part is the MD5 hashed E-Mail address of the user and the latter part is a [Universally unique identifier](https://en.wikipedia.org/wiki/Universally_unique_identifier). Encoding the user information in the API key has the advantage to be able to directly lookup the `User` entity via it's key, compared to a costly query. Since the E-Mail is not encoded directly, we don't expose sensitive information.\n\nThe responsible function for looking up users from OpenID Connect or API keys is `getUser` in [api.py](backend/progress/api.py).\n\n#### Authorization\n\nAuthenticated users (either via OpenID Connect or API key) are authorized to create new progresses and manipulate their own progresses.\n\n`progressApi` will respond with an error code `401 - Unauthorized` when authorization fails.\n\n## Clients\n\n**gae-progress** provides a collection of clients that are able to communicate with `progressApi`. These are\n - [Web App](clients/www) - a AngularJS web application written in JavaScript.\n - [Python-gapi](clients/python-gapi) - A Python command line client using the Google APIs client library.\n - [Cpp/Qt](clients/cpp-qt5) - A C++ command line client using the Qt library.\n - [Java](clients/java) - A Java command line client using generated code from Google Endpoints Tool.\n\n## Acknowledgement\n\nThis work is greatly sponsored by [PROFACTOR GmbH](http://www.profactor.at) - creators of [ReconstructMe](http://reconstructme.net).\n\n## License\n```\nCopyright Christoph Heindl 2016\n\ngae-progress is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\ngae-progress is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with gae-progress. If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheind%2Fgae-progress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcheind%2Fgae-progress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheind%2Fgae-progress/lists"}