Giter VIP home page Giter VIP logo

shiny.reglog's Introduction

shiny.reglog

Lifecycle: stable CRAN status CRAN checks Codecov test coverage R-CMD-check

1. Introduction

The user authentication in Shiny applications can be very useful. Mainly, user can login to read and write some results of their session into relational database.

On the other hand, it may be handy for your App to allow access of unregistered users. If you need to secure your ShinyApp, there are better alternatives (shinymanager or shinyauthr)

This package contains modules to use in your Shiny application allowing you to automatically insert boxes for login, register, credentials edit and password reset and procedures.

shiny.reglog supports as data containers either databases accessed with RSQLite, RMariaDB, RMySQL and RPostgreSQL drivers or googlesheets-based database (accessed by googlesheets4 package).

It is highly recommended to use one of the DBI-supported databases, though. It is much more optimized and secure, as the database is never loaded as a whole into the memory, but queried as needed. googlesheets database is much easier to set-up, but it shouldn’t be used when you are expecting big userbase.

Registration, credentials edit and password reset procedures programmatically send email to the user of your ShinyApp - to welcome them, inform about change of their user ID and/or email and to give them a reset code to reset their password. shiny.reglog supports two methods of email sending: via emayili or gmailr packages. Both of them have their pros and cons, depending on your accesses: emayili allows for usage of many SMTP servers, while gmailr allowing using gmail messaging via Google REST API.

The emayili is recommended for most applications. gmailr can be useful if you already have application registered and authorized with mail sending scope.

Currently the package is after major change in its code - basically full rewrite to allow more security, usage of more databases and more customization. Past functions are still available in current version, but will generate deprecation warnings.

2. Additional information

Basic information about shiny.reglog is contained within this document. There are some more resources to learn about its usage:

  • You can access demonstration shinyApp with showcase mode on shinyapps.io
  • You can run interactive demo in your own RStudio by using RegLogDemo() function. It will use mocked mailConnector by default or RegLogEmayiliConnector if you provide it arguments required by emayili backend.
  • For more information read vignettes.

3. Basic structure

There are three main objects that are to be used when implementing RegLog system for login and registration in your ShinyApp. All of them need to be defined in the server code.

  • dbConnector: one of RegLogDBIConnector or RegLogGsheetConnector. It will handle all writes, edits and inputs to the users database.
  • mailConnector: one of RegLogEmayiliConnector or RegLogGmailrConnector. It will handle all automatical emailing to the user emails.
  • RegLogServer: The main module producing and controlling all of UI and reactivity of the login and registration system. It uses dbConnector and mailConnector for actions external of R.

4. Installation

You can install this version of shiny.reglog from GitHub with:

# install last stable release from CRAN
install.packages("shiny.reglog")

## or development version from GitHub
install.packages("devtools")
devtools::install.github("StatisMike/shiny.reglog")

5. Setting up dbConnector

You need to create dbConnector object to be used by the RegLogServer to write and read user data from the database.

To set-up the database for RegLog system, you can use helper functions included in this package. They are tested and guarantee compatible structure of the data.

5.1 Googlesheet database method (RegLogGsheetConnector)

  1. Create googlesheet file on your googledrive to support database. You can use gsheet_tables_create() function, which by default creates empty spreadsheets configured correctly.
# create googlesheet and gather its id for later usage
# you can also specify optional 'name' argument for custom gsheet name

gsheet_id <- gsheet_tables_create()

# save you gsheet_id - you need to provide it later to your dbConnector

If you wish to import some existing credentials, you can do it by giving the data.frame object to the user_data argument:

# get some credentials
credentials <- data.frame(
  username = "ShinyReglogTest",
  password = "VeryHardPassword",
  email = "shinyreglog@test"
  )

# create gsheet database with some credentials
gsheet_id <- gsheet_tables_create(
  user_data = credentials,
  # as the password was not hashed with `script` before, 
  # it need to be hashed now
  hash_passwords = T)
  1. Configure googlesheets4 package to use out-of-band (non-interactive) auth. For more information about it visit googlesheets4 documentation.

  2. In the server part of your ShinyApp define RegLogGsheetConnector to provide it afterwards to the RegLogServer object

server <- function(input, output, session) {
  
  dbConnector <- RegLogGsheetConnector$new(
    gsheet_ss = gsheet_id)
  
}

5.2 DBI compatible SQL database (RegLogDBIConnector)

RegLog system out of the box supports SQLite, MySQL, MariaDB and PostgreSQL databases. You can use DBI_tables_create function, which by default creates empty tables configured correctly.

# create a connection to the database. Remember to use user with CREATE TABLE
# scope enabled when useing MySQL, MariaDB or PostgreSQL connection

conn <- DBI::dbConnect(
  RSQLite::SQLite(),
  dbname = "reglog_db.sqlite"
)

# using this connection create the tables.
DBI_tables_create(conn = conn)

# disconnect from the database after creation
DBI::dbDisconnect(conn)

If you wish to import some credentials, you can do it by providing the data.frame object to the user_data argument:

# get some credentials
credentials <- data.frame(
  username = "ShinyReglogTest",
  password = "VeryHardPassword",
  email = "shinyreglog@test")

conn <- DBI::dbConnect(
  RSQLite::SQLite(),
  dbname = "reglog_db.sqlite"
)

# create database using the connection
DBI_tables_create(
  conn = conn,
  user_data = credentials,
  # as the password was not hashed with `script` before, 
  # it need to be hashed now
  hash_passwords = T)

DBI::dbDisconnect(conn)
  1. In the server part of your ShinyApp define RegLogDBIConnector to provide it afterwards to the RegLogServer object.
server <- function(input, output, session) {
  
  dbConnector <- RegLogDBIConnector$new(
    driver = RSQLite::SQLite(),
    dbname = "reglog_db.sqlite")
  
}

5.3. MongoDB-based connector (RegLogMongoConnector)

MongoDB is very popular NoSQL database with pretty low entry-point. Connector is still experimental.

Setup is analogous to other database connectors. For more informations, refer to documentation: ?mongo_tables_create(), ?RegLogMongoConnector

6. Setting up mail connectors

You need to create mailConnector object to be used by the RegLogServer to write and read user data from the database. There are two classes defined to use emayili or gmailr packages as backend.

6.1. Using emayili (RegLogEmayiliConnector)

This backend is recommended to use. It supports many SMTP servers, mostly with username and password based identification.

server <- function(input, output, session) {
  
  mailConnector <- RegLogEmayiliConnector$new(
    from = "[email protected]",
    # to learn how to setup emayili smtp server read ?emayili::server
    smtp = emayili::server(...)
  )
  
}

6.2. Using gmailr (RegLogGmailrConnector)

This backend is only viable if you have an app registered in Google Cloud Console. It authorizes and sends email via gmail REST API, needing Oauth authorization with high scopes.

server <- function(input, output, session) {
  
  mailConnector <- RegLogGmailrConnector$new(
    from = "[email protected]"
  )
  
}

7. Setup RegLogServer

All of RegLog system is generated and maintained by the object of class RegLogSystem in unison with dbConnector and mailConnector of your choosing.

Its setup is pretty straightforward:

server <- function(input, output, session) {
  
  RegLog <- RegLogServer$new(
    # both of these elements need to be defined firstly or in this call
    dbConnector = dbConnector,
    mailConnector = mailConnector
  )
}

Besides these two mandatory arguments, there are also some additional arguments to be used for customization.

  • app_name: your application name. It will be used within emails send to users. If not specified, the name of the folder containing you application files will be used.
  • app_address: URL address to your application. It will be used within emails send to users. If not specified, the email address contained within session$clientData will be used.
  • lang: language to be used in UI elements and send emails. Defaults to ‘en’ for English. Currently also ‘pl’ for Polish is supported. Besides that, you can also specify ‘i18’ to generate only text indicators - external methods can be used to parse the message in given language can be then used (eg. shiny.i18n package).
  • custom_txts: named list with character strings of custom texts to be used by the system. For more information call ?RegLog_txt.
  • use_modals: either boolean indicating if all default modalDialogs should be shown or named list of FALSE values inhibiting specific ones. For more information read RegLogServer object fields and methods, section Message. All modals are listed there alongside conditions of their appearance.
  • module_id: character string with ID of the module. Recommended to leave as default - unless if that name is taken by another module.

7.1. Retrieve information from RegLogServer

After setting up and assigning the object your application logic can observe status of user in current session by public fields containing reactiveVal objects.

## if you assigned the RegLogServer to 'RegLog' object, as in examples above:

# boolean showing if the user is logged in:
RegLog$is_logged()

# character vector containing user ID: either specific to the user if logged
# in, or unique anonymous ID generated with 'uuid::UUIDgenerate()'
RegLog$user_id()

# character vector containing user email if logged in
RegLog$user_mail()

# integer of the account ID inside the database - for identifying the logged user
# across relative tables
RegLog$account_id()

There are much more to be learned about RegLogServer object - for more information read RegLogServer object fields and methods. Above information is enough for basic setup.

8. Insert UI elements

Every part of the UI is generated by RegLogServer, and could be accessed by provided functions containing tagList.

8.1. Login UI

Providing GUI to allow logging in if user is already registered to your application.

RegLog_login_UI()

8.2. Register UI

Providing GUI for registering new account.

  • Both user ID and e-mail needs to be unique within the databasa
  • user ID need to consist of 8-30 alphanumeric characters
  • user password need to consist of 8-30 characters. It needs to contain characters of at least 3 of 4 following groups:
    • small letter
    • big letter
    • number
    • special character
  • user email is also validated

After account registration, user will receive confirmation email on their password.

RegLog_register_UI()

8.3. Credentials edit UI

Providing GUI for changing credentials.

  • user need to be logged in to change their data
  • to confirm their identity, they need to provide their current password
  • user can change either during one interaction:
    • password
    • user ID and/or e-mail
  • same checks as in register procedure are conducted
  • after user ID and/or e-mail change user will receive confirmation e-mail
RegLog_credsEdit_UI()

8.4. Reset password UI

Providing GUI for password reset.

  • in the case of user forgetting their password, they can reset it by providing their user ID
  • mail message containing reset code will be sent to the user
  • inputing the reset code from e-mail will allow password change
  • same password check for new password is conducted as in register procedure
RegLog_resetPass_UI()

shiny.reglog's People

Contributors

cainesap avatar statismike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

shiny.reglog's Issues

Create tests with `shinyTest`

Create shinyTest tests for functions which need shiny interactivity.

  • RegLogSystem with RegLogEmayiliConnector and RegLogDBIConnector
  • RegLogSystem with RegLogGmailrConnector and RegLogGsheetConnector
  • login_server with db_method = "sqlite" and mail_method = "emayili
  • login_server with db_method = "gsheet" and mail_method = "gmailr`

Tests for deprecated system have been dropped. Manual testing was conducted.

Email verification link

Hi @StatisMike,
This is a very useful library, thanks! I was wondering if it's possible to add an email verification link or code that allows us to verify that the registered user actually has access to that email? Similar to what is already done with the reset password feature.

Logout button

The feature that wasn't thought of initially, but may be handy - simple logout button.

Correct typos in registration text

  • User ID and password should consist of 8~30 characters. For user ID every alphanumeric characters are valid. Password should contain at least three out of four following types of characters: big letter, small letter, number, special character.
  • You should have access to the provided e-mail address. After registration you will receive a confirmation e-mail. Moreover, if you ever forget your password you can reset it with reset code send to provided e-mail.

Please see corrected text below:

  • User ID and password should consist of 8~30 characters. For user ID any alphanumeric characters are valid. Password should contain at least three out of four of the following types of characters: capital letters, lowercase letters, numbers, special characters.
  • You should have access to the provided e-mail address. After registration you will receive a confirmation e-mail. Moreover, if you ever forget your password you can reset it with reset code sent to the provided e-mail.

Support SQLite database encryption

Currently, the SQLite database used to keep the information of the users is not protected by any kind of hashing method. For securing it further such encryption should be added.

Encryption similar to used by shinymanager is planned

Modify default modalDialog logic

Refactor all modals logic from using old modals_check to modals_check_n_show. Connected to #28

  • login_noInput
  • login_badId
  • login_badPass
  • login_success
  • register_noInput
  • register_nonValidId
  • register_nonValidEmail
  • register_nonValidPass
  • register_notIdenticalPass
  • register_existingId
  • register_existingEmail
  • register_success
  • credsEdit_noInput_pass
  • credsEdit_noInput_other
  • credsEdit_nonValidId
  • credsEdit_nonValidEmail
  • credsEdit_nonValidPass
  • credsEdit_notIdenticalPass
  • credsEdit_badId
  • credsEdit_badPass
  • credsEdit_existingId
  • credsEdit_existingEmail
  • credsEdit_success
  • resetPass_noInput_generate
  • resetPass_noInput_confirm
  • resetPass_nonValidPass
  • resetPass_notIdenticalPass
  • resetPass_badId
  • resetPass_codeGenerated
  • resetPass_nonValidCode
  • resetPass_success
  • logout_notLogIn
  • logout_success

Rework `reglog_txt` into `RegLog_txt`.

Every text that is appearing anywhere in the UI or in modalDialogs need to be unique object - even if there are duplicates. Will make more elastic for anyone who would like to customize something.

Create seperate language object

Currently, the lines visible to the users are hard coded into their respective calls. It has numerous flaws:

  • the code is cluttered, hard to read and generally not-elegant
  • it makes the development of support for more languages hard

Create tests with `testthat`

Create testthat tests for all functions that don't require shinyApp interactivity:

  • RegLog_txt / reglog_txt
  • DBI_tables_create / create_sqlite_db
  • gsheet_tables_create / create_gsheet_db

Add dbConnector supporting MongoDB databases

As document-based NoSQL are popular with all sorts of small applications, I feel like there is also a need for supporting them.

Although they are more elastic in their schemas, there is also a possibility to use them for storing SQL-like, relational data, just like data created and menaged by shiny.reglog.

As MongoDB seems to be the most popular NoSQL ATM, first dbConnector will be created for its support. Possibilities for making general dbConnector for multiple NoSQL databases will also be explored.

Refactor into `R6` based modules

R6 helps to mantain the code as clear as possible. Moreover, using R6 shiny modules makes interreactivity between the module and rest of the application straightforward.

Because of this, it is planned to refactor the whole logic and make the reglog system based on R6 classes initialized within the server.

As the package is in stable stage and is present on CRAN, old functions will get deprecated rather than removed.

Additional changes planned:

  • all changes in the state of internal logic will be trackable
  • the googlesheets4, RSQLite, emayili and gmailr dependencies will be removed
  • the default state will be implying the custom logic behind database and email sending defined by the user

Unpipe the whole code

Currently there is extensive use of pipe %>% in the code for the whole package. It is unadvisable to do so for the package to be accepted into CRAN, as it makes the code harder to debug.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.