Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BE-777 Fix an issue of authentication #140

Merged
merged 1 commit into from
Jul 14, 2020
Merged
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
54 changes: 40 additions & 14 deletions README-CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,45 @@ This document will describe about the detail of each configuration:
* `expiresIn`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms).
Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).

* Modify the connection profile (e.g. `app/platform/fabric/connection-profile/first-network.json`) to configure authorization of login user.

```json
"client": {
"adminCredential": {
"id": "exploreradmin",
"password": "exploreradminpw"
},
"enableAuthentication": true,
```
* `adminCredential.id` is the the admin user to login Explorer. Currently Explorer only supports single user mode (can't add more users. We're working on it)
* `adminCredential.password` is the password for the admin user to login Explorer.
* `enableAuthentication` is a flag to enable authentication using a login page, setting to false will skip authentication.
* Even if disable user authentication, you still need to get `adminCredential.id` specified, because it's used to get access to the wallet.

## Disable Explorer login authentication

* If you want to disable login authentication, set `false` to `enableAuthentication` in the connection profile
```json
"client": {
"enableAuthentication": false
}
```

## Enable TLS

* If your fabric network enables TLS, then set `true` to `client.tlsEnable` in the connection profile (e.g. `app/platform/fabric/connection-profile/first-network.json`).
And you also need to specify peer URL with `grpcs://`. If your fabrice network disables TLS, use `grpc://` instead.

```json
"client": {
"tlsEnable": true,
```
```json
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
```

## Connection profile for Hyperledger Fabric network

* Modify `app/platform/fabric/config.json` to define your fabric network connection profile:
Expand All @@ -51,8 +90,7 @@ This document will describe about the detail of each configuration:
"network-configs": {
"first-network": {
"name": "firstnetwork",
"profile": "./connection-profile/first-network.json",
"enableAuthentication": false
"profile": "./connection-profile/first-network.json"
}
},
"license": "Apache-2.0"
Expand All @@ -76,18 +114,6 @@ This document will describe about the detail of each configuration:
"pem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMG ... utE5HtrGM\n-----END PRIVATE KEY-----\n"
},
```
* `adminUser` is the the admin user of the network, in this case it's fabric CA or an identity user.
* `adminPassword` is the password for the admin user.
* `enableAuthentication` is a flag to enable authentication using a login page, setting to false will skip authentication.

## Disable Explorer login authentication

* If you want to disable login authentication, set `false` to `enableAuthentication` in the connection profile
```json
"client": {
"enableAuthentication": false
}
```

## Using Fabric-CA

Expand Down
2 changes: 1 addition & 1 deletion app/passport/local-login.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const strategy = function(platform) {
network: userInfo.network
};

if (userInfo && !userInfo.authenticated) {
if (!userInfo || !userInfo.authenticated) {
const error = {
name: 'IncorrectCredentialsError',
message: userInfo.message
Expand Down
1 change: 0 additions & 1 deletion app/platform/fabric/FabricClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ class FabricClient {
// Getting channels from queryChannels
let channels;
try {
// logger.debug('this.defaultPeer ', this.defaultPeer);
channels = await this.fabricGateway.queryChannels();
} catch (e) {
logger.error(e);
Expand Down
10 changes: 2 additions & 8 deletions app/platform/fabric/Proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,8 @@ class Proxy {
*/
async authenticate(user) {
const userService = new UserService(this.platform);
let response = await userService.authenticate(user);
if (!response) {
response = {
status: false,
message: `Failed authentication for user: ${user} `
};
}
logger.debug('login >> %s', response);
const response = await userService.authenticate(user);
logger.debug('result of authentication >> %j', response);
return response;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"network-configs": {
"org1-network": {
"name": "org1-network",
"profile": "./e2e-test/configs/connection-profile/org1-network-disable-auth.json"
}
},
"license": "Apache-2.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "org1-network",
"version": "1.0.0",
"license": "Apache-2.0",
"client": {
"tlsEnable": true,
"adminCredential": {
"id": "exploreradmin3"
},
"enableAuthentication": false,
"organization": "org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
},
"orderer": "300"
}
}
},
"channels": {
"commonchannel": {
"peers": {
"peer0-org1": {}
},
"connection": {
"timeout": {
"peer": {
"endorser": "6000",
"eventHub": "6000",
"eventReg": "6000"
}
}
}
}
},
"organizations": {
"org1": {
"mspid": "Org1ExampleCom",
"adminPrivateKey": {
"path": "./app/platform/fabric/e2e-test/specs/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/keystore/priv_sk"
},
"peers": ["peer0-org1"],
"signedCert": {
"path": "./app/platform/fabric/e2e-test/specs/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/signcerts/Admin@org1-cert.pem"
}
}
},
"peers": {
"peer0-org1": {
"tlsCACerts": {
"path": "./app/platform/fabric/e2e-test/specs/crypto-config/peerOrganizations/org1/peers/peer0-org1.org1/tls/ca.crt"
},
"url": "grpcs://localhost:31000",
"grpcOptions": {
"ssl-target-name-override": "peer0-org1"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"client": {
"tlsEnable": true,
"adminCredential": {
"id": "exploreradmin",
"id": "exploreradmin2",
"password": "exploreradminpw"
},
"enableAuthentication": false,
"enableAuthentication": true,
"organization": "org1",
"connection": {
"timeout": {
Expand Down Expand Up @@ -39,18 +39,18 @@
"org1": {
"mspid": "Org1ExampleCom",
"adminPrivateKey": {
"pem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgMwFI31oAw7BLotqD\nlt83zXPSFdcG9s68O8xjsmuEcDChRANCAAQeGSJN2yd9m1m0rRnXnO2/kjiZywRE\nIpjVDyBArAgoFwIAVgmkkps4NI3EMPMBXiTw8NTHjeEEkuovbohNAEal\n-----END PRIVATE KEY-----\n\n"
"pem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTOe+tIgG/TCjBruv\na5namOzeiEGhNxV+wYke2Ya7vXqhRANCAATux7xsRpKYrTJv18qJPfI8ypWrjcno\nzs9pF0UsrT2zKfaKPouGT3Tl58DujHvwXbM68FKQPiA86GA4AKrSMpZx\n-----END PRIVATE KEY-----\n\n"
},
"peers": ["peer0-org1"],
"signedCert": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICBTCCAaugAwIBAgIQKSCQe3pGrCx15SgsHg6I+TAKBggqhkjOPQQDAjBbMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzENMAsGA1UEChMEb3JnMTEQMA4GA1UEAxMHY2Eub3JnMTAeFw0yMDA3\nMTAxNTIyMDBaFw0zMDA3MDgxNTIyMDBaMF8xCzAJBgNVBAYTAlVTMRMwEQYDVQQI\nEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ4wDAYDVQQLEwVh\nZG1pbjETMBEGA1UEAwwKQWRtaW5Ab3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABB4ZIk3bJ32bWbStGdec7b+SOJnLBEQimNUPIECsCCgXAgBWCaSSmzg0jcQw\n8wFeJPDw1MeN4QSS6i9uiE0ARqWjTTBLMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMB\nAf8EAjAAMCsGA1UdIwQkMCKAIJnau5jo0eUJwITnEe/wl2pg0gmtYvYsfYPKQy8t\nM/4ZMAoGCCqGSM49BAMCA0gAMEUCIQDiqNYuzalWflQQizqyjeZ0wynW395RZ9Ix\n7wVivlZNcQIgDWIDMnponNx8eSmv0f4ISJJtvsmTNFGSwpoGzpKWQ2s=\n-----END CERTIFICATE-----\n\n"
"pem": "-----BEGIN CERTIFICATE-----\nMIIB9DCCAZugAwIBAgIQOiMkd2Zh+BDeMU+pGOsfdzAKBggqhkjOPQQDAjBbMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzENMAsGA1UEChMEb3JnMTEQMA4GA1UEAxMHY2Eub3JnMTAeFw0yMDA3\nMTQwNjI3MDBaFw0zMDA3MTIwNjI3MDBaME8xCzAJBgNVBAYTAlVTMRMwEQYDVQQI\nEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQDDApB\nZG1pbkBvcmcxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7se8bEaSmK0yb9fK\niT3yPMqVq43J6M7PaRdFLK09syn2ij6Lhk905efA7ox78F2zOvBSkD4gPOhgOACq\n0jKWcaNNMEswDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQw\nIoAg0W6Kv0Z9DV5E+3sD6OErwjsJ882ogeeGzrB9jCBwZ74wCgYIKoZIzj0EAwID\nRwAwRAIgG6fqi1lB4sjcosYRbO2YxDYJ92jmvR6FqCqKOXtwSQQCIGnXgTzNGvof\np1DFPz5c3DKmgjQlok2MAlKn6z01JRBM\n-----END CERTIFICATE-----\n\n"
}
}
},
"peers": {
"peer0-org1": {
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICJzCCAc2gAwIBAgIQTjoDncZ/NWffVrgB449RmTAKBggqhkjOPQQDAjBeMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzENMAsGA1UEChMEb3JnMTETMBEGA1UEAxMKdGxzY2Eub3JnMTAeFw0y\nMDA3MTAxNTIyMDBaFw0zMDA3MDgxNTIyMDBaMF4xCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK\nEwRvcmcxMRMwEQYDVQQDEwp0bHNjYS5vcmcxMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEXREuqNRHBPddBxwWT+01LZzkLjnFHhI0j+xpcGvLurqSpHwuh8XEe+nW\ncN2vzP6v16W6F2pjiYrqTwAvwrwUfqNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCCRDXS4hPlBUrW2wLu+fNy2PYfY1maQe1b6eLXjgoXclzAKBggqhkjOPQQD\nAgNIADBFAiEA3vNlfA2AKI9+lFHVKl9MD3+ZLN4M0K1HYlfx2BkuZToCIG7Nky+/\nPOT1iS3XCRPfZq4EAd4S2hQs5i7vuXB0b47o\n-----END CERTIFICATE-----\n\n"
"pem": "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIQRckhJx+KJbD5liP6bky2SjAKBggqhkjOPQQDAjBeMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzENMAsGA1UEChMEb3JnMTETMBEGA1UEAxMKdGxzY2Eub3JnMTAeFw0y\nMDA3MTQwNjI3MDBaFw0zMDA3MTIwNjI3MDBaMF4xCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK\nEwRvcmcxMRMwEQYDVQQDEwp0bHNjYS5vcmcxMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEVzX85nYUlr/Kc8kWYcdr2L4ICp1GURWDgG0oZd9X6ATZUj2yghcTk6hh\nKvawyyfVuH95S3johA3WZzzRW537FaNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCDkk8d226n5IMJh9RwUaanA3lDDErXkSXT9uTUhA++3lDAKBggqhkjOPQQD\nAgNHADBEAiBx7YneCm31nYCo8kk7LD1gLbMeW//ItePlwLjYtowGcwIgPdjuHCOX\nH+U/87Z4PvNbNdoDi4a22Bg8BPIPRISxYjU=\n-----END CERTIFICATE-----\n\n"
},
"url": "grpcs://localhost:31000",
"grpcOptions": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"password": "exploreradminpw",
"affiliation": "org1.department1"
},
"enableAuthentication": false,
"enableAuthentication": true,
"organization": "org1",
"connection": {
"timeout": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"affiliation": "org2.department1"
},
"organization": "org2",
"enableAuthentication": false,
"enableAuthentication": true,
"connection": {
"timeout": {
"peer": {
Expand Down
84 changes: 72 additions & 12 deletions app/platform/fabric/e2e-test/specs/apitest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const (
waitSyncInterval = 7
)

func basicCheck() {
func basicCheck(loginId string) {

It("get network list", func() {

Expand All @@ -52,12 +52,23 @@ func basicCheck() {

It("login to org1-network", func() {

resp := restPost("/auth/login", map[string]interface{}{"user": "exploreradmin", "password": "exploreradminpw", "network": "org1-network"}, &LoginResponse{})
resp := restPost("/auth/login", map[string]interface{}{"user": loginId, "password": "exploreradminpw", "network": "org1-network"}, &LoginResponse{})
result := resp.Result().(*LoginResponse)
token = result.Token

Expect(resp.StatusCode()).Should(Equal(200))
Expect(result.Success).Should(Equal(true))
Expect(result.User.Message).Should(Equal("logged in"))
Expect(result.User.Name).Should(Equal("exploreradmin"))
Expect(result.User.Name).Should(Equal(loginId))
})

It("fail to login with invalid credential", func() {

resp := restPost("/auth/login", map[string]interface{}{"user": loginId, "password": "invalid", "network": "org1-network"}, &LoginResponse{})
result := resp.Result().(*LoginResponse)

Expect(resp.StatusCode()).Should(Equal(400))
Expect(result.Success).Should(Equal(false))
})

It("get channels", func() {
Expand Down Expand Up @@ -169,15 +180,15 @@ var _ = Describe("REST API Test Suite - Single profile", func() {
os.RemoveAll("./logs")
os.Chdir(cwd)

cmd := exec.Command("./runexplorer.sh", "single")
cmd := exec.Command("bash", "./runexplorer.sh", "-m", "single")
err := cmd.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(isExplorerReady, 60, 5).Should(Equal(true))

time.Sleep(waitSyncInterval * time.Second)
})

basicCheck()
basicCheck("exploreradmin")

XIt("register user", func() {
resp := restPostWithToken("/api/register", map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}, &RegisterResp{}, token)
Expand All @@ -201,7 +212,7 @@ var _ = Describe("REST API Test Suite - Single profile", func() {
})

It("stop explorer", func() {
_, err := networkclient.ExecuteCommand("./stopexplorer.sh", []string{}, true)
_, err := networkclient.ExecuteCommand("bash", []string{"./stopexplorer.sh"}, true)
Expect(err).NotTo(HaveOccurred())
})

Expand All @@ -211,15 +222,36 @@ var _ = Describe("REST API Test Suite - Single profile", func() {
os.RemoveAll("./logs")
os.Chdir(cwd)

cmd := exec.Command("./runexplorer.sh", "single-pem")
cmd := exec.Command("bash", "./runexplorer.sh", "-m", "single-pem")
err := cmd.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(isExplorerReady, 60, 5).Should(Equal(true))

time.Sleep(waitSyncInterval * time.Second)
})

basicCheck("exploreradmin2")

It("stop explorer, but persist data and wallet", func() {
_, err := networkclient.ExecuteCommand("bash", []string{"./stopexplorer.sh", "-k"}, true)
Expect(err).NotTo(HaveOccurred())
})

It("restart explorer", func() {
cwd, _ := os.Getwd()
os.Chdir(relativePahtToRoot)
os.RemoveAll("./logs")
os.Chdir(cwd)

cmd := exec.Command("bash", "./runexplorer.sh", "-m", "single-pem", "-k")
err := cmd.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(isExplorerReady, 60, 5).Should(Equal(true))

time.Sleep(waitSyncInterval * time.Second)
})

basicCheck()
basicCheck("exploreradmin2")

Describe("Bugfix check:", func() {

Expand Down Expand Up @@ -277,7 +309,35 @@ var _ = Describe("REST API Test Suite - Single profile", func() {
})

It("stop explorer", func() {
_, err := networkclient.ExecuteCommand("./stopexplorer.sh", []string{}, true)
_, err := networkclient.ExecuteCommand("bash", []string{"./stopexplorer.sh"}, true)
Expect(err).NotTo(HaveOccurred())
})

It("launch explorer - disable authentication", func() {
cwd, _ := os.Getwd()
os.Chdir(relativePahtToRoot)
os.RemoveAll("./logs")
os.Chdir(cwd)

cmd := exec.Command("bash", "./runexplorer.sh", "-m", "single-disable-auth")
err := cmd.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(isExplorerReady, 60, 5).Should(Equal(true))

time.Sleep(waitSyncInterval * time.Second)
})

It("succeed to login with invalid credential", func() {

resp := restPost("/auth/login", map[string]interface{}{"user": "invalid", "password": "invalid", "network": "org1-network"}, &LoginResponse{})
result := resp.Result().(*LoginResponse)

Expect(resp.StatusCode()).Should(Equal(200))
Expect(result.Success).Should(Equal(true))
})

It("stop explorer", func() {
_, err := networkclient.ExecuteCommand("bash", []string{"./stopexplorer.sh"}, true)
Expect(err).NotTo(HaveOccurred())
})

Expand Down Expand Up @@ -326,7 +386,7 @@ var _ = Describe("REST API Test Suite - Multiple profile", func() {
inputSpecPath = "apitest-input-multiprofile.yml"

By("0) Generating channel artifacts")
_, err := networkclient.ExecuteCommand("./genchannelartifacts.sh", []string{}, true)
_, err := networkclient.ExecuteCommand("bash", []string{"./genchannelartifacts.sh"}, true)
Expect(err).NotTo(HaveOccurred())

By("1) Creating channel")
Expand Down Expand Up @@ -369,7 +429,7 @@ var _ = Describe("REST API Test Suite - Multiple profile", func() {
os.RemoveAll("./logs")
os.Chdir(cwd)

cmd := exec.Command("./runexplorer.sh", "multi")
cmd := exec.Command("bash", "./runexplorer.sh", "-m", "multi")
err := cmd.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(isExplorerReady, 60, 5).Should(Equal(true))
Expand Down Expand Up @@ -695,7 +755,7 @@ var _ = Describe("REST API Test Suite - Multiple profile", func() {
// })

It("stop explorer", func() {
_, err := networkclient.ExecuteCommand("./stopexplorer.sh", []string{}, true)
_, err := networkclient.ExecuteCommand("bash", []string{"./stopexplorer.sh"}, true)
Expect(err).NotTo(HaveOccurred())
})

Expand Down
Loading