Skip to content

Commit

Permalink
[FEATURE][auth] OAuth2 authentication method plugin
Browse files Browse the repository at this point in the history
- Supports authentication code, implicit and resource owner grant flows
- Allows for preconfigured connections, read from default locations
- Offers caching of access token beyond QGIS restarts
- Save/load configurations
- Has documentation written

Sponsored by Monsanto Company
  • Loading branch information
dakcarto committed Oct 27, 2017
1 parent 90857b2 commit 244e886
Show file tree
Hide file tree
Showing 36 changed files with 6,912 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/auth/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ ADD_SUBDIRECTORY(basic)
ADD_SUBDIRECTORY(identcert)
ADD_SUBDIRECTORY(pkipaths)
ADD_SUBDIRECTORY(pkipkcs12)

SET(WITH_OAUTH2_PLUGIN TRUE CACHE BOOL "Build OAuth2 authentication method plugin")
IF (WITH_OAUTH2_PLUGIN)
ADD_SUBDIRECTORY(oauth2)
ENDIF (WITH_OAUTH2_PLUGIN)
189 changes: 189 additions & 0 deletions src/auth/oauth2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# OAuth 2 Authentication Method plugin

########################################################
# Packages
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})

IF(NOT QTKEYCHAIN_FOUND)
FIND_PACKAGE(QtKeychain REQUIRED)
ENDIF()
OPTION(WITH_INTERNAL_O2 "Download and locally include source of o2 library" ON)

IF(WITH_INTERNAL_O2)
INCLUDE(DownloadO2)
SET(O2_SOURCE_DIR ${O2_INCLUDE_DIR})
ELSE()
FIND_PACKAGE(O2 REQUIRED)
ENDIF()

########################################################
# Source files

SET(OAUTH2_SRCS
qgso2.cpp
qgsauthoauth2config.cpp
qgsauthoauth2method.cpp
qgsauthoauth2edit.cpp
qjsonwrapper/Json.cpp
)
IF(WITH_INTERNAL_O2)
SET(O2_SRCS
${O2_SOURCE_DIR}/o0baseauth.cpp
${O2_SOURCE_DIR}/o0keychainstore.cpp
${O2_SOURCE_DIR}/o0settingsstore.cpp
${O2_SOURCE_DIR}/o2.cpp
${O2_SOURCE_DIR}/o2reply.cpp
${O2_SOURCE_DIR}/o2replyserver.cpp
${O2_SOURCE_DIR}/o2requestor.cpp
${O2_SOURCE_DIR}/o2simplecrypt.cpp
)
SET(OAUTH2_SRCS ${OAUTH2_SRCS} ${O2_SRCS})
ENDIF()

SET(OAUTH2_HDRS
qgso2.h
qgsauthoauth2config.h
qgsauthoauth2method.h
qgsauthoauth2edit.h
qjsonwrapper/Json.h
)
IF(WITH_INTERNAL_O2)
SET(O2_HDRS
${O2_INCLUDE_DIR}/o0abstractstore.h
${O2_INCLUDE_DIR}/o0baseauth.h
${O2_INCLUDE_DIR}/o0export.h
${O2_INCLUDE_DIR}/o0globals.h
${O2_INCLUDE_DIR}/o0keychainstore.h
${O2_INCLUDE_DIR}/o0requestparameter.h
${O2_INCLUDE_DIR}/o0settingsstore.h
${O2_INCLUDE_DIR}/o0simplecrypt.h
${O2_INCLUDE_DIR}/o2.h
${O2_INCLUDE_DIR}/o2reply.h
${O2_INCLUDE_DIR}/o2replyserver.h
${O2_INCLUDE_DIR}/o2requestor.h
)
SET(OAUTH2_HDRS ${OAUTH2_HDRS} ${O2_HDRS})
ENDIF()

SET(OAUTH2_MOC_HDRS
qgso2.h
qgsauthoauth2config.h
qgsauthoauth2method.h
qgsauthoauth2edit.h
)
IF(WITH_INTERNAL_O2)
SET(O2_MOC_HDRS
${O2_INCLUDE_DIR}/o0abstractstore.h
${O2_INCLUDE_DIR}/o0baseauth.h
${O2_INCLUDE_DIR}/o0keychainstore.h
${O2_INCLUDE_DIR}/o0settingsstore.h
${O2_INCLUDE_DIR}/o2.h
${O2_INCLUDE_DIR}/o2reply.h
${O2_INCLUDE_DIR}/o2replyserver.h
${O2_INCLUDE_DIR}/o2requestor.h
)
SET(OAUTH2_MOC_HDRS ${OAUTH2_MOC_HDRS} ${O2_MOC_HDRS})
ENDIF()

SET(OAUTH2_UIS qgsauthoauth2edit.ui)

SET(OAUTH2_RCCS oauth2_resources.qrc)

# Common includes
INCLUDE_DIRECTORIES (
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
INCLUDE_DIRECTORIES (SYSTEM
${QCA_INCLUDE_DIR}
${QTKEYCHAIN_INCLUDE_DIR}
${O2_INCLUDE_DIR}
)
INCLUDE_DIRECTORIES (
${CMAKE_SOURCE_DIR}/src/core
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/geometry
${CMAKE_SOURCE_DIR}/src/auth/oauth2
${CMAKE_SOURCE_DIR}/src/gui
${CMAKE_SOURCE_DIR}/src/gui/auth
${CMAKE_BINARY_DIR}/src/core
${CMAKE_BINARY_DIR}/src/gui
${CMAKE_BINARY_DIR}/src/ui
${CMAKE_BINARY_DIR}/src/ui/auth
${CMAKE_BINARY_DIR}/src/auth/oauth2
)

############################################################
# Generate files
IF(WITH_INTERNAL_O2 AND CMAKE_GENERATOR MATCHES "Ninja")
# handle `cmake --help-policy CMP0058`
# "Ninja requires custom command byproducts to be explicit,"
# which the downloaded o2 source files are not. Add phony command target...
ADD_CUSTOM_COMMAND(
OUTPUT ${O2_HDRS}
COMMAND
)
ENDIF()
QT4_WRAP_UI(OAUTH2_UIS_H ${OAUTH2_UIS})

QT4_WRAP_CPP(OAUTH2_MOC_SRCS ${OAUTH2_MOC_HDRS})

QT4_ADD_RESOURCES(OAUTH2_RCC_SRCS ${OAUTH2_RCCS})
############################################################
# Set up plugin targets

ADD_LIBRARY (oauth2authmethod MODULE
${OAUTH2_SRCS}
${OAUTH2_HDRS}
${OAUTH2_MOC_SRCS}
${OAUTH2_RCC_SRCS}
${OAUTH2_UIS_H}
)

# For unit testing
ADD_LIBRARY (oauth2authmethod_static STATIC
${OAUTH2_SRCS}
${OAUTH2_HDRS}
${OAUTH2_MOC_SRCS}
${OAUTH2_RCC_SRCS}
${OAUTH2_UIS_H}
)

# Common linked libs
SET(OAUTH2_TARGET_LIBS ${QTKEYCHAIN_LIBRARY})

IF(NOT WITH_INTERNAL_O2)
IF(NOT "${O2_LIBRARY}" STREQUAL "")
# prefer dynamic linking
SET(OAUTH2_TARGET_LIBS ${OAUTH2_TARGET_LIBS} ${O2_LIBRARY})
ELSE()
SET(OAUTH2_TARGET_LIBS ${OAUTH2_TARGET_LIBS} ${O2_LIBRARY_STATIC})
ENDIF()
#message(STATUS "OAUTH2_TARGET_LIBS: ${OAUTH2_TARGET_LIBS}")
ENDIF()

SET(OAUTH2_TARGET_LIBS
qgis_core
qgis_gui
${OAUTH2_TARGET_LIBS}
)

TARGET_LINK_LIBRARIES (oauth2authmethod
${OAUTH2_TARGET_LIBS}
)
TARGET_LINK_LIBRARIES (oauth2authmethod_static
${OAUTH2_TARGET_LIBS}
)

if(WIN32)
add_definitions(-DO2_DLL_EXPORT)
ENDIF()

########################################################
# Install

# don't install static variant, as it's only for unit testing from build directory
INSTALL(TARGETS oauth2authmethod
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR}
)
66 changes: 66 additions & 0 deletions src/auth/oauth2/cmake/DownloadO2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Download Module for o2 Library Source
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright (c) March 2017, Boundless Spatial
# Author: Larry Shaffer <lshaffer (at) boundlessgeo (dot) com>
#
# Official o2 project source code repository: https://github.com/pipacs/o2
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.

# NOTE: These is a temporary source code commit checkout, until a releas with
# recent commits is available via common platform packaging
set(_o2_commit 31ceafb3f0c3b605110ddd20aeebd3288504ee1f)
set(_o2_url "https://github.com/pipacs/o2/archive/${_o2_commit}.tar.gz")
set(_o2_dl_file "${CMAKE_BINARY_DIR}/o2-${_o2_commit}.tar.gz")
set(_o2_dl_sha1 94236af3c373927d778349cdbe89ff6112343cc9)
set(_o2_dl_timeout 45)
set(_o2_dl_inactive_timeout 30)

set(_o2_prefix "${CMAKE_BINARY_DIR}/o2-${_o2_commit}")

message(STATUS "Downloading or verifying o2 library source archive...")

file(DOWNLOAD ${_o2_url} ${_o2_dl_file}
INACTIVITY_TIMEOUT ${_o2_dl_inactive_timeout}
TIMEOUT ${_o2_dl_timeout}
STATUS _o2_dl_status
LOG _o2_dl_log
#SHOW_PROGRESS
EXPECTED_HASH SHA1=${_o2_dl_sha1}
TLS_VERIFY on
#TLS_CAINFO file
)

list(GET _o2_dl_status 0 _o2_dl_status_code)
list(GET _o2_dl_status 1 _o2_dl_status_string)

if(NOT "${_o2_dl_status_code}" STREQUAL "0")
set(_o2_dl_log_file ${CMAKE_BINARY_DIR}/o2-download.log)
set(_o2_dl_log_title "Error downloading or verifying o2 library source archive")
set(_o2_dl_log_msg "${_o2_dl_log_title}
from url=${_o2_url}
to file =${_o2_dl_file}
timeout =${_o2_dl_timeout} seconds
status code: ${_o2_dl_status_code}
status string: ${_o2_dl_status_string}
connection log:
${_o2_dl_log}
")
file(WRITE ${_o2_dl_file} "${_o2_dl_log_msg}")
message(FATAL_ERROR "${_o2_dl_log_title}
See log: ${_o2_dl_log_file}
")
endif()

if(NOT EXISTS ${_o2_dl_file})
message(FATAL_ERROR "Download file does not exist")
endif()

execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${_o2_dl_file})

# These match variables set by FindO2.cmake
set(O2_INCLUDE_DIR "${_o2_prefix}/src" CACHE INTERNAL "Path to o2 library headers" FORCE)
set(O2_LIBRARY "" CACHE INTERNAL "Path to o2 built shared library" FORCE)
set(O2_LIBRARY_STATIC "" CACHE INTERNAL "Path to o2 built static library" FORCE)
set(O2_FOUND TRUE CACHE INTERNAL "Whether O2 has been found" FORCE)
59 changes: 59 additions & 0 deletions src/auth/oauth2/cmake/FindO2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Find O2
# ~~~~~~~~~
# Copyright (c) 2016, Monsanto Company, USA
# Author: Larry Shaffer, <lshaffer (at) boundlessgeo (dot) com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# CMake module to search for O2 OAuth 1/2 library from:
# https://github.com/pipacs/o2
#
# If it's found it sets O2_FOUND to TRUE
# and following variables are set:
# O2_INCLUDE_DIR
# O2_LIBRARY
# O2_LIBRARY_STATIC

IF (O2_INCLUDE_DIR AND (O2_LIBRARY OR O2_LIBRARY_STATIC))
SET(O2_FOUND TRUE)

ELSE (O2_INCLUDE_DIR AND (O2_LIBRARY OR O2_LIBRARY_STATIC))

FIND_PATH(O2_INCLUDE_DIR o2.h
PATHS
/usr/include
/usr/local/include
"$ENV{LIB_DIR}/include"
$ENV{INCLUDE}
PATH_SUFFIXES o2
)
FIND_LIBRARY(O2_LIBRARY NAMES o2
PATHS
/usr/local/lib
/usr/lib
"$ENV{LIB_DIR}/lib"
"$ENV{LIB}"
)
FIND_LIBRARY(O2_LIBRARY_STATIC NAMES libo2.a libo2_static.a o2_static
PATHS
/usr/local/lib
/usr/lib
"$ENV{LIB_DIR}/lib"
"$ENV{LIB}"
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(O2 DEFAULT_MSG O2_LIBRARY O2_INCLUDE_DIR)

ENDIF (O2_INCLUDE_DIR AND (O2_LIBRARY OR O2_LIBRARY_STATIC))

IF (O2_FOUND)
IF (NOT O2_FIND_QUIETLY)
MESSAGE(STATUS "Found O2: ${O2_LIBRARY} ${O2_LIBRARY_STATIC}")
ENDIF (NOT O2_FIND_QUIETLY)
ELSE (O2_FOUND)
IF (O2_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find O2")
ENDIF (O2_FIND_REQUIRED)
ENDIF (O2_FOUND)
69 changes: 69 additions & 0 deletions src/auth/oauth2/cmake/FindQJSON.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Find QJSON - JSON handling library for Qt
#
# Copyright (c) 2016, Monsanto Company, USA
# Author: Larry Shaffer, <lshaffer (at) boundlessgeo (dot) com>
#
# Culled from QJson 0.7.1 release
#
# This module defines
# QJSON_FOUND - whether the qsjon library was found
# QJSON_LIBRARIES - the qjson library
# QJSON_INCLUDE_DIR - the include path of the qjson library
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.

if (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)

# Already in cache
set (QJSON_FOUND TRUE)

else (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)

# if (NOT WIN32)
# # use pkg-config to get the values of QJSON_INCLUDE_DIRS
# # and QJSON_LIBRARY_DIRS to add as hints to the find commands.
# include (FindPkgConfig)
# pkg_check_modules (QJSON REQUIRED QJson>=0.8)
# endif (NOT WIN32)

find_library (QJSON_LIBRARIES
NAMES qjson qjson-qt5
PATHS
${QJSON_LIBRARY_DIRS}
"$ENV{OSGEO4W_ROOT}/lib"
/usr/local/lib
/usr/lib
"$ENV{LIB_DIR}/lib"
"$ENV{LIB}"
${LIB_INSTALL_DIR}
${KDE4_LIB_DIR}
)

find_path (QJSON_INCLUDE_DIR
NAMES qjson/parser.h
PATHS
${QJSON_INCLUDE_DIRS}
"$ENV{OSGEO4W_ROOT}/include"
/usr/include
/usr/local/include
"$ENV{LIB_DIR}/include"
$ENV{INCLUDE}
${INCLUDE_INSTALL_DIR}
${KDE4_INCLUDE_DIR}
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(QJSON DEFAULT_MSG QJSON_LIBRARIES QJSON_INCLUDE_DIR)

endif (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)

if (QJSON_FOUND)
if (NOT QJSON_FIND_QUIETLY)
message(STATUS "Found QJson: ${QJSON_LIBRARIES}")
endif (NOT QJSON_FIND_QUIETLY)
else (QJSON_FOUND)
if (NOT QJSON_FIND_QUIETLY)
message(FATAL_ERROR "Could not find QJson")
endif (NOT QJSON_FIND_QUIETLY)
endif (QJSON_FOUND)
Loading

0 comments on commit 244e886

Please sign in to comment.