Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"image": "mcr.microsoft.com/devcontainers/universal:2",
"image": "mcr.microsoft.com/devcontainers/universal:3",
"features": {
"ghcr.io/akhildevelops/devcontainer-features/apt:0": {
"PACKAGES": "gtk-doc-tools docbook-xsl yelp-tools libpng-dev libgtk-3-dev libicu-dev libjson-glib-dev intltool autopoint xxd libcurl4-gnutls-dev libglib2.0-dev-bin libsqlite3-dev nettle-dev libmapnik-dev libgeoclue-2-dev libgexiv2-dev libgps-dev libmagic-dev libbz2-dev libzip-dev liboauth-dev libnova-dev yaru-theme-icon"
"PACKAGES": "gtk-doc-tools docbook-xsl yelp-tools libpng-dev libgtk-3-dev libicu-dev libjson-glib-dev intltool autopoint xxd libcurl4-gnutls-dev libglib2.0-dev-bin libsqlite3-dev nettle-dev libmapnik-dev libgeoclue-2-dev libgexiv2-dev libgps-dev libmagic-dev libbz2-dev libzip-dev liboauth-dev libnova-dev yaru-theme-icon librest-dev"
}
},
"mounts": [
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/build-variants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ jobs:
strategy:
fail-fast: false
matrix:
# v----------------------- Optional library components -----------------------------------------v v----------------code features -----------------v
no-variants: [bzip2, geoclue, geotag, magic, mapnik, mbtiles, nova, nettle, oauth, realtime-gps-tracking, zip, bing, google, bluemarble, geonames, openstreetmap]
# v----------------------- Optional library components ----------------------------------v v----------------code features -----------------v
no-variants: [bzip2, geoclue, geotag, magic, mapnik, mbtiles, nova, nettle, realtime-gps-tracking, zip, bing, google, bluemarble, geonames, openstreetmap]

# NB specifically limited to single OS variant and default GTK, in order to keep number of runs within reason
# Thus much more likely to keep within overall compute quota limits for a given time period
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v3
Expand All @@ -25,7 +25,7 @@ jobs:
# regarding ubuntu default image vs server packages mismatch
# Hence must always *update* before applying any install
- name: "Install requirements"
run: sudo apt-get update -y && sudo apt-get install gtk-doc-tools docbook-xsl yelp-tools libpng-dev libgtk-3-dev libicu-dev libjson-glib-dev intltool autopoint xxd libcurl4-gnutls-dev libglib2.0-dev-bin libsqlite3-dev nettle-dev libmapnik-dev libgeoclue-2-dev libgexiv2-dev libgps-dev libmagic-dev libbz2-dev libzip-dev liboauth-dev libnova-dev
run: sudo apt-get update -y && sudo apt-get install gtk-doc-tools docbook-xsl yelp-tools libpng-dev libgtk-3-dev libicu-dev libjson-glib-dev intltool autopoint xxd libcurl4-gnutls-dev libglib2.0-dev-bin libsqlite3-dev nettle-dev libmapnik-dev libgeoclue-2-dev libgexiv2-dev libgps-dev libmagic-dev libbz2-dev libzip-dev liboauth-dev librest-dev libnova-dev
shell: bash

# Should work without the optional library component being installed - but ATM not going bother (de)configuring the OS
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04]
os: [ubuntu-24.04]
libgtk: [libgtk-3-dev, libgtk2.0-dev]

runs-on: ${{ matrix.os }}
Expand All @@ -24,7 +24,7 @@ jobs:
# Hence must always *update* before applying any install
# xvfb is only needed for headless CI tests
- name: "Install requirements"
run: sudo apt-get update -y && sudo apt-get install gtk-doc-tools docbook-xsl yelp-tools libpng-dev ${{ matrix.libgtk }} libicu-dev libjson-glib-dev intltool autopoint xxd libcurl4-gnutls-dev libglib2.0-dev-bin libsqlite3-dev nettle-dev libmapnik-dev libgeoclue-2-dev libgexiv2-dev libgps-dev libmagic-dev libbz2-dev libzip-dev liboauth-dev libnova-dev xvfb
run: sudo apt-get update -y && sudo apt-get install gtk-doc-tools docbook-xsl yelp-tools libpng-dev ${{ matrix.libgtk }} libicu-dev libjson-glib-dev intltool autopoint xxd libcurl4-gnutls-dev libglib2.0-dev-bin libsqlite3-dev nettle-dev libmapnik-dev libgeoclue-2-dev libgexiv2-dev libgps-dev libmagic-dev libbz2-dev libzip-dev liboauth-dev libnova-dev librest-dev xvfb
shell: bash

# Fake DISPLAY for detection as used in configure - which decides which tests to run for the main check
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ help/C/*html
/src/vikenumtypes.h
/src/vikenumtypes.c
/src/documenters.h
/src/osm-oauth2-example

# /src/libjpeg
/src/libjpeg/*.o
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ On Debian Sid, the following packages must be installed before building:

The following packages are needed (they are included by default in Debian Sid, but not in other distributions). They must be installed too:

$ sudo apt-get install libcurl4-gnutls-dev libglib2.0-dev-bin
$ sudo apt-get install libcurl4-gnutls-dev libglib2.0-dev-bin librest-dev

The following packages are also used, but they can each be disabled with configure options, if desired:

Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ PKG_CHECK_MODULES(PACKAGE, [
gio-2.0 >= 2.32
gdk-pixbuf-2.0 >= 2.26
json-glib-1.0 >= 0.16
rest-1.0 >= 0.9
])

AC_SUBST(PACKAGE_CFLAGS)
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

SUBDIRS = icons

bin_PROGRAMS = viking
bin_PROGRAMS = viking osm-oauth2-example

noinst_LIBRARIES = \
libviking.a
Expand Down Expand Up @@ -199,6 +199,7 @@ endif
if OPENSTREETMAP
libviking_a_SOURCES += \
osm.c osm.h \
osm_api_client.c osm_api_client.h \
osm-traces.c osm-traces.h \
datasource_osm_my_traces.c \
datasource_osm.c
Expand Down
157 changes: 157 additions & 0 deletions src/osm-oauth2-example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/* gitlab-oauth2-example.c
*
* Copyright 2021 Günther Wagner <info@gunibert.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/

/**
* This example shows the recommended PKCE authorization flow for Gitlab.
*/

#include <glib.h>
#include <rest/rest.h>
#include <stdio.h>
#include <libsoup/soup.h>



GMainLoop *loop;

static void
fetch_logged_in_user(RestProxy *proxy)
{
g_autoptr(GError) error = NULL;
RestProxyCall *call;

call = rest_proxy_new_call (proxy);
rest_proxy_call_set_method (call, "GET");
rest_proxy_call_set_function (call, "/user/details");
rest_proxy_call_sync (call, &error);

g_print ("%s\n", rest_proxy_call_get_payload (call));
g_main_loop_quit (loop);
}

static void
osm_oauth2_example_refreshed_access_token (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
RestOAuth2Proxy *oauth2_proxy = (RestOAuth2Proxy *)object;
g_autoptr(GError) error = NULL;

g_assert (G_IS_OBJECT (object));
g_assert (G_IS_ASYNC_RESULT (result));

rest_oauth2_proxy_refresh_access_token_finish (oauth2_proxy, result, &error);
if (error)
g_error ("%s", error->message);

g_print ("Access Token: %s\n", rest_oauth2_proxy_get_access_token (oauth2_proxy));
g_print ("Refresh Token: %s\n", rest_oauth2_proxy_get_refresh_token (oauth2_proxy));
GDateTime *expiration_date = rest_oauth2_proxy_get_expiration_date (oauth2_proxy);
if (expiration_date)
g_print ("Expires in: %s\n", g_date_time_format (expiration_date, "%X %x"));

fetch_logged_in_user (REST_PROXY (oauth2_proxy));
}

static void
osm_oauth2_example_fetched_access_token (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
RestOAuth2Proxy *oauth2_proxy = (RestOAuth2Proxy *)object;
g_autoptr(GError) error = NULL;

g_assert (G_IS_OBJECT (object));
g_assert (G_IS_ASYNC_RESULT (result));

rest_oauth2_proxy_fetch_access_token_finish (oauth2_proxy, result, &error);
if (error)
g_error ("%s", error->message);

g_print ("Access Token: %s\n", rest_oauth2_proxy_get_access_token (oauth2_proxy));
g_print ("Refresh Token: %s\n", rest_oauth2_proxy_get_refresh_token (oauth2_proxy));
GDateTime *expiration_date = rest_oauth2_proxy_get_expiration_date (oauth2_proxy);
if (expiration_date)
g_print ("Expires in: %s\n", g_date_time_format (expiration_date, "%X %x"));

fetch_logged_in_user (REST_PROXY (oauth2_proxy));

/* refresh token */
rest_oauth2_proxy_refresh_access_token_async (oauth2_proxy, NULL, osm_oauth2_example_refreshed_access_token, user_data);
}

gint
main (gint argc,
gchar *argv[])
{
g_autofree gchar *line = NULL;
size_t len = 0;

gchar **environment = g_get_environ ();
gchar *authurl = "https://www.openstreetmap.org/oauth2/authorize";
gchar *tokenurl = "https://www.openstreetmap.org/oauth2/token";
gchar *redirecturl = "urn:ietf:wg:oauth:2.0:oob";
gchar *baseurl = "https://api.openstreetmap.org/api/0.6/";


// ID 2ovOGzjSEA1W7ebG7D8aqyVvFPfs6RJW_TLweVcsPJk
// x1_mDnLQbSgOvw2fFSde5WIKrTJH1v4tV4FFwCJMQc4
const gchar *clientid = g_environ_getenv (environment, "REST_OAUTH2_CLIENT_ID");
if (!clientid)
{
g_print ("You have to define your OpenStreetMap Client ID as REST_OAUTH2_CLIENT_ID environment variable\n");
return EXIT_SUCCESS;
}
// Secret annkUVUxacqmfqzOYMG3Bs8mNtjUH7SddoO4Nt7GRas
// DKop7jo1FbXBW9J9B-wk85pOyQCQxrt8hQ7s9Srgz0A
const gchar *clientsecret = g_environ_getenv (environment, "REST_OAUTH2_CLIENT_SECRET");
if (!clientsecret)
{
g_print ("You have to define your OpenStreetMap Client Secret as REST_OAUTH2_CLIENT_SECRET environment variable\n");
return EXIT_SUCCESS;
}
RestPkceCodeChallenge *pkce = rest_pkce_code_challenge_new_random ();
gchar *state = NULL;

#ifdef WITH_SOUP_2
SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_HEADERS, -1);
#else
SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_HEADERS);
#endif

RestOAuth2Proxy *oauth2_proxy = rest_oauth2_proxy_new (authurl, tokenurl, redirecturl, clientid, clientsecret, baseurl);
rest_proxy_add_soup_feature (REST_PROXY (oauth2_proxy), SOUP_SESSION_FEATURE (logger));
const gchar *authorize_url = rest_oauth2_proxy_build_authorization_url (oauth2_proxy, rest_pkce_code_challenge_get_challenge (pkce), "openid", &state);

g_print ("URL to authorize: %s\n", authorize_url);

ssize_t chars = getline (&line, &len, stdin);
if (line[chars - 1] == '\n') {
line[chars - 1] = '\0';
}

g_print ("Got Authorization Grant: %s\n", line);

/* fetch access token */
rest_oauth2_proxy_fetch_access_token_async (oauth2_proxy, line, rest_pkce_code_challenge_get_verifier (pkce), NULL, osm_oauth2_example_fetched_access_token, NULL);

loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);

return 0;
}
Loading