mobile-security-service

module
v0.0.0-...-d4224cb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2019 License: Apache-2.0

README

ifdef::env-github[]
:status:
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
:table-caption!:
endif::[]


:toc:
:toc-placement!:

= Mobile Security Service

ifdef::status[]
.*Project health*
image:https://circleci.com/gh/aerogear/mobile-security-service.svg?style=svg[Build Status (CircleCI), link=https://circleci.com/gh/aerogear/mobile-security-service]
image:https://img.shields.io/:license-Apache2-blue.svg[License (License), link=http://www.apache.org/licenses/LICENSE-2.0]
image:https://coveralls.io/repos/github/aerogear/mobile-security-service/badge.svg?branch=master[Coverage Status (Coveralls), link=https://coveralls.io/github/aerogear/mobile-security-service?branch=master]
image:https://goreportcard.com/badge/github.com/aerogear/mobile-security-service[Go Report Card (Go Report Card), link=https://goreportcard.com/report/github.com/aerogear/mobile-security-service]
endif::[]

:toc:
toc::[]

== Overview

This is the server component of the AeroGear Mobile Security Service. It is a RESTful API that allows developers to view, enable and disable specific versions of applications on demand, with the information stored in a PostgreSQL database.

== Prerequisites

|===
|https://golang.org/doc/install[Install Golang]
|https://github.com/golang/go/wiki/SettingGOPATH[Ensure the $GOPATH environment variable is set]
|https://golang.github.io/dep/docs/installation.html[Install the dep package manager]
|https://docs.docker.com/compose/install/[Install Docker and Docker Compose]
|===

== Getting Started

If you'd like to simply run the entire application in `docker-compose`, follow link:#16-running-entire-application-with-docker-compose[these instructions].

Golang projects are kept in a https://golang.org/doc/code.html#Workspaces[workspace] that follows a very specific architecture. Before cloning this repo, be sure you have a `$GOPATH` environment variable set up.

:numbered:
=== Cloning the Repository

[source,shell]
----
git clone git@github.com:aerogear/mobile-security-service.git $GOPATH/src/github.com/aerogear/mobile-security-service
----
=== Change to correct working directory

[source,shell]
----
cd $GOPATH/src/github.com/aerogear/mobile-security-service
----

=== Installing Dependencies

[source,shell]
----
make setup
----

NOTE: This is using the `dep` package manager under the hood. You will see the dependencies installed in the `vendor` folder.

=== Configuring the Database

This REST Service is using a https://www.postgresql.org/[PostgreSQL] database. The server will not start without a https://www.postgresql.org/[PostgreSQL] available.
There are two ways to install the database:

==== By using the docker image of this project

* Removing any existing docker Postgres containers

[source,shell]
----
$ docker rm <container_id>
----

* Starting the database container

[source,shell]
----
$ docker-compose up -d db
----

NOTE: When the database is started the link:./pkg/db/db.go[db.go] routine will be executed and the database model will be created.

TIP: You can use https://www.pgadmin.org/[pgadmin] to work with the database. See link:#installing-and-configuring-client-tool-for-the-database[Installing and configuring client tool for the database]

* Checking the database

. Run `$ docker ps` to get the `container id`
. Run `$ docker exec -it <postgres-container-id> bash` to access the container via shell
. Run `psql -U postgres` to login with the user `postgres` in the database
. Run `\c mobile_security_service` to connect to the database created for this project
. Run `\dt` to lists all tables in the current database

==== By using a local Postgres DB

In the link:#database[Database] section you can see the default values which will be used by the link:./pkg/config/config.go[config.go] routine.

. Set up your local database and/or change the configuration defined.
. Create the database and tables in your local PostgreSQL installation. See the file link:./pkg/db/db.go[db.go] to get the scripts to create the tables.

NOTE: The file link:./pkg/config/config.go[config.go] will use the default values, however, if would like to change them it should be made by link:#environment-variables[Environment Variables], see the topic link:#adding-your-own-.env-file[Adding your own .env file]

=== Starting the Server

[source,shell]
----
go run cmd/mobile-security-service/main.go
----

Starting the Server and the web UI
[source,shell]
----
make serve
----

=== Checking REST Service

Run the following curl command and check the output is as shown.

[source,shell]
----
$ curl localhost:3000/api/apps
[{"id":"0890506c-3dd1-43ad-8a09-21a4111a65a6","appId":"com.aerogear.testapp","appName":"Test App","numOfDeployedVersions":2,"numOfCurrentInstalls":3,"numOfAppLaunches":6000},{"id":"1b9e7a5f-af7c-4055-b488-72f2b5f72266","appId":"com.aerogear.foobar","appName":"Foobar","numOfDeployedVersions":0,"numOfCurrentInstalls":0,"numOfAppLaunches":0}]
----

NOTE: This endpoint will return all apps saved in the database. If you do not have data saved locally it will return no data with a `204 No Content` response code.

TIP: You can install the https://www.getpostman.com/[Postman] tool which will be useful to call and test the REST API endpoints of this server.
Following an image to show how it works.

=== Running Entire Application with Docker Compose

This section shows how to start the entire application with `docker-compose`. This is useful for doing some quick tests (using the SDKs) for example.

First, compile a Linux compatible binary:

[source,shell]
----
go build -o mobile-security-service cmd/mobile-security-service/main.go
----

This binary will be used to build the Docker image. Now start the entire application.

[source,shell]
----
docker-compose up
----
:numbered!:

== Setup and configurations

=== Environment Variables

The **mobile-security-service** is configured using environment variables.

* By default, the application will look for system environment variables to use.
* If a system environment variable cannot be found, the application will then check the `.env` file in the application root.
* If the `.env` file does not exist, or if the variable is not defined in the file, the application will use the default value defined in link:./pkg/config/config.go[config.go].

=== Adding your own .env file

Make a copy of the example file `.env.example`.

[source,shell]
----
cp .env.example .env
----

Now the application will use the values defined in `.env`.

=== Server Configuration

|===
| *Variable* | *Default* | *Description*
| PORT                             | 3000    | The port the server will listen on
| LOG_LEVEL                        | info    | Can be one of `[debug, info, warning, error, fatal, panic]`
| LOG_FORMAT                       | text    | Can be one of `[text, json]`
| ACCESS_CONTROL_ALLOW_ORIGIN      | *       | Can be multiple URL values separated with commas. Example: `ACCESS_CONTROL_ALLOW_ORIGIN=http://www.example.com,http://example.com`
| ACCESS_CONTROL_ALLOW_CREDENTIALS | false   | Can be one of `[true, false]`
| DBMAX_CONNECTIONS                | 100     | The maximum number of concurrent database connections the server will open
|===

== Database

The database connection is configured using the table of environment variables below. These environment variables correspond to the PostgreSQL https://www.postgresql.org/docs/current/static/libpq-envars.html[libpq environment variables]. The table below shows all of the environment variables supported by the `pq` driver used in this server.

|===
| *Variable*        | *Default*               | *Description*                                                                                                                                  
| PGDATABASE        | mobile_security_service | The database to connect to                                                                                                                   
| PGUSER            | postgresql              | The database user                                                                                                                            
| PGPASSWORD        | postgres                | The database password                                                                                                                        
| PGHOST            | localhost               | The database hostname to connect to                                                                                                          
| PGPORT            | 5432                    | The database port to connect to                                                                                                              
| PGSSLMODE         | disable                 | The SSL mode                                                                                                                                 
| PGCONNECT_TIMEOUT | 5                       | The default connection timeout (seconds)                                                                                                     
| PGAPPNAME         |                         | The https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-APPLICATION-NAME[application_name] connection parameter
| PGSSLCERT         |                         | The https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-SSLCERT[sslcert] connection parameter.
| PGSSLKEY          |                         | The https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-SSLKEY[sslkey] connection parameter.
| PGSSLROOTCERT     |                         | The https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-SSLROOTCERT[sslrootcert] connection parameter
|===         

=== Database Entity Relationship Diagram

image::https://user-images.githubusercontent.com/1596014/54042089-3bd7c200-41c1-11e9-8a55-b3eda5253a51.png[Diagram]

== Development information for contributors

=== Using Swagger UI

==== By browser

The swagger api doc is generated in link:./api/swagger.yaml[/api/swagger.yaml] and you can check the REST API definition with this file by using the https://petstore.swagger.io/[Demo] tool online for swaggerUI or https://chrome.google.com/webstore/detail/swagger-ui-console/ljlmonadebogfjabhkppkoohjkjclfai?hl=en[Chrome extension].
Paste https://raw.githubusercontent.com/aerogear/mobile-security-service/master/api/swagger.yaml[https://raw.githubusercontent.com/aerogear/mobile-security-service/master/api/swagger.yaml] and press **Explore**.

==== By docker

A https://swagger.io/[Swagger] UI can be used for testing the mobile-security-service service.

[source,shell]
----
docker run -p 8080:8080 -e API_URL=https://raw.githubusercontent.com/aerogear/mobile-security-service/master/api/swagger.yaml swaggerapi/swagger-ui
----

Or you can run the container with `docker-compose up -d swagger`.

The Swagger UI is available at http://localhost:8080[localhost:8080].

=== Building & Testing

The `Makefile` provides commands for building and testing the code. Some dependencies are required to run these commands.

==== Installing the required dependencies

Dependencies may be required to run some of the `Make` commands. Below are instructions on how to install them.

Run the following command.

[source,shell]
----
$ go get -u github.com/matryer/moq
----

NOTE : See all commands available in link:#using-make-commands[Using make commands]

=== Installing and configuring client tool for the database

You can use https://www.pgadmin.org/[pgadmin] which is the client tool for PostgreSQL to work with the database.

* Download and install the client tool

NOTE: The link to download for MacOS is : https://www.pgadmin.org/download/pgadmin-4-macos/

* Configure the client tool

Following the steps to do this setup.

. Access the tool via the browser. The default link will be `http://127.0.0.1:52263/browser/#`
. Create a new server connection with the database. Following the image to show how to do it.


image::https://user-images.githubusercontent.com/7708031/53171792-9ecf3380-35db-11e9-8de7-4a7df979b38b.png[Create Server,align="center"]

. Add the data required to connect to the database. See the values defined in link:./pkg/config/config.go[config.go]. Following an image with this setup.

image::https://user-images.githubusercontent.com/7708031/53172136-857ab700-35dc-11e9-9794-4fa016703135.png[Configuration,640,align="center"]

=== Adding data to test the Service

Use the scripts from the file link:./pkg/helpers/db_seed.go[db_seed.go]. It will allow you have data to check this service.

=== Creating mock files for the interfaces

This project is using the dependency https://github.com/matryer/moq[moq]. Follow the steps below to use it.

* Creating the mock file

Execute the following command to generate the mock file.

[source,shell]
----
$ moq -out <name_of_mock_file> . <name of interface>
----

Example:

[source,shell]
----
moq -out apps_service_mock.go . Service
----

IMPORTANT: This command need to be executed from the same directory where the interface is or it need to be called as, for example, `$ moq -out ./pkg/web/apps/apps_service_mock.go ./pkg/web/apps Service`

NOTE: See more over it in the Readme of https://github.com/matryer/moq[moq]

* Using the mock

In the created file you will see an implementation commented as in the following example. This implementation will be used in the test file to mock the methods/func of this interface.

[source,go]
----
// AppServiceMock is a mock implementation of Service.
//
//     func TestSomethingThatUsesAppService(t *testing.T) {
//
//         // make and configure a mocked Service
//         mockedAppService := &AppServiceMock{
//             GetAppsFunc: func() (*[]models.App, error) {
// 	               panic("mock out the GetApps method")
//             },
//         }
//
//         // use mockedAppService in code that requires Service
//         // and then make assertions.
//
//     }
----

* Mocking interfaces

The `panic` statement needs to be replaced for the mock data. Following an example.

[source,go]
----
numOfDeployedVersions := 5
numOfAppLaunches := 1000
numOfCurrentInstalls := 9000

// mock data
app := models.App{
    ID:                    "a0874c82-2b7f-11e9-b210-d663bd873d93",
    AppID:                 "com.aerogear.app1",
    AppName:               "app1",
    NumOfDeployedVersions: &numOfDeployedVersions,
    NumOfAppLaunches:      &numOfAppLaunches,
    NumOfCurrentInstalls:  &numOfCurrentInstalls,
}

// make and configure a mocked Service
mockedAppService := &AppServiceMock{
    GetAppsFunc: func() (*[]models.App, error) {
        return &[]models.App{
            app,
        }, nil
    },
}
----

* Calling the mock

You will call the mock instead of use the interface. It will return the data mocked as defined above. Following an practical example.

[source,go]
----
func Test_HttpHandler_GetApps(t *testing.T) {
	// make and configure a mocked Service
	mockedAppService := &AppServiceMock{
		GetAppsFunc: func() (*[]models.App, error) {
			return &[]models.App{
				*helpers.GetMockApp(),
			}, nil
		},
	}

	// Setup
	e := echo.New()
	req := httptest.NewRequest(http.MethodGet, "/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	c.SetPath("/api/apps")
	h := &httpHandler{mockedAppService}
}
----

NOTE: The mock file generated by the dep contains comments which will help you to understand how to use it.

=== Using make commands

|===
| *Command*                       | *Description*
| `make setup`                  | Downloads dependencies into `vendor`
| `make setup-githooks`         | Symlink all Git hooks from `.githooks` into `.git/hooks`
| `make build`                  | Compile a binary compatible with your current system into `./mobile-security-service`
| `make build-linux`            | Compile a Linux binary into `./dist/linux_amd64/mobile-security-service`
| `make build-swagger-api`      | Generate swagger API documentation from the source code
| `make build-image`            | Compile a binary and create an image from it.
| `make build-release-image`    | Compile a binary and create an image with a release tag
| `make build-master-image`     | Compile a binary and create an image tagged `master`
| `make serve`                  | Runs the server and the UI together
| `make test`                   | Runs unit tests
| `make test-all`               | Runs all tests
| `make test-integration`       | Runs integration tests
| `make test-integration-cover` | Runs integration tests and outputs results to a log file
| `make errcheck`               | Checks for unchecked errors using https://github.com/kisielk/errcheck[errcheck]
| `make vet`                    | Examines source code and reports suspicious constructs using https://golang.org/cmd/vet/[vet]
| `make fmt`                    | Formats code using https://golang.org/cmd/gofmt/[gofmt]
| `make clean`                  | Removes binary compiled using `make build`
| `make push-release-image`     | Pushes release image to image hosting repository
| `make push-master-image`      | Pushes master image to image hosting repository
| `make cleanup-coverage-file`  | Removes lines from the coverage report that do not need to be included
|===

NOTE: The link:./Makefile[Makefile] is implemented with tasks which you should use to work with.

== Built With

* https://golang.org/[Golang] - Programming language used
* https://echo.labstack.com/[Echo] - Web framework used

== Release

Following the steps

* Create a new tag following the http://semver.org/spec/v2.0.0.html[semver], for example:

[source,shell]
----
$ git tag -a 0.1.0 -m "version 0.1.0"
----

* Push the new tag to the upstream repository, for example:

[source,shell]
----
$ git push upstream 0.1.0
----

* Update the the link:./CHANGELOG.MD[CHANGELOG.MD] with the new release.

NOTE: The image with the tag will be created and pushed to the https://quay.io/repository/aerogear/mobile-security-service[mobile-security-service image repository] by the CI.

WARNING: Do not use letters in the tag such as `v`. It will not work.

== Contributing

All contributions are hugely appreciated. Please see our https://aerogear.org/community/#guides[Contributing Guide] for guidelines on how to open issues and pull requests. Please check out our link:./.github/CODE_OF_CONDUCT.md[Code of Conduct] too.

== Questions

There are a number of ways you can get in in touch with us, please see the https://aerogear.org/community/#contact[AeroGear community].

Directories

Path Synopsis
cmd
mobile-security-service
API for Mobile Security Service This is a sample mobile security service server.
API for Mobile Security Service This is a sample mobile security service server.
pkg
db

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL