50 | );
51 | };
52 |
53 | AppLayout.propTypes = {
54 | classes: PropTypes.object.isRequired,
55 | children: PropTypes.any.isRequired
56 | };
57 |
58 | export default withStyles(styles)(AppLayout);
59 |
60 |
--------------------------------------------------------------------------------
/components/portal/src/utils/api/dataUtils.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | /**
20 | * Data (returned from the API) related utilities.
21 | */
22 | class DataUtils {
23 |
24 | /**
25 | * Get the name to be displayed for a user object returned from the API.
26 | *
27 | * @param {Object} userData The user data object returned from the API.
28 | * @returns {string} The display name to be used in the Portal
29 | */
30 | static getUserDisplayName(userData) {
31 | let displayName = "";
32 | if (userData) {
33 | if (userData.displayName) {
34 | displayName = userData.displayName;
35 | } else if (userData.email) {
36 | displayName = userData.email.split("@")[0];
37 | } else {
38 | throw Error("Either the displayName or the email need to be present in the provided user, "
39 | + `received ${JSON.stringify(userData)}`);
40 | }
41 | } else {
42 | throw Error(`Unable to get display for empty user data, received ${userData}`);
43 | }
44 | return displayName;
45 | }
46 |
47 | }
48 |
49 | export default DataUtils;
50 |
--------------------------------------------------------------------------------
/components/portal/src/components/sdk/appLayout/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import Container from "@material-ui/core/Container";
20 | import Footer from "../../appLayout/Footer";
21 | import Header from "./Header";
22 | import React from "react";
23 | import {withStyles} from "@material-ui/core/styles";
24 | import * as PropTypes from "prop-types";
25 |
26 | const styles = () => ({
27 | root: {
28 | display: "flex",
29 | minHeight: "100vh",
30 | flexDirection: "column"
31 | },
32 | mainContent: {
33 | flex: 1
34 | }
35 | });
36 |
37 | const SDKAppLayout = (props) => {
38 | const {classes, children} = props;
39 |
40 | return (
41 |
50 | );
51 | };
52 |
53 | SDKAppLayout.propTypes = {
54 | classes: PropTypes.object.isRequired,
55 | children: PropTypes.any.isRequired
56 | };
57 |
58 | export default withStyles(styles)(SDKAppLayout);
59 |
60 |
--------------------------------------------------------------------------------
/components/proxy/database/lock.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | import ballerina/log;
20 |
21 | # Acquire the write lock from the MySQL DB.
22 | #
23 | # Lock this path by acquiring the MySQL write lock. Since this is in a transaction auto commit will be switched off.
24 | # This allows the proxy to run in HA mode and lock the image pushing across replicas.
25 | #
26 | # + imageFQN - imageFQN Fully qualified Cell Image name
27 | # + return - error if an error occurred
28 | public function acquireWriteLockForImage(string imageFQN) returns error? {
29 | _ = check celleryHubDB->update(LOCK_QUERY, imageFQN);
30 | }
31 |
32 | # Cleanup any data usd in acquiring the write lock.
33 | #
34 | # + imageFQN - imageFQN Parameter Description
35 | public function cleanUpAfterLockForImage(string imageFQN) {
36 | var lockCleanupResult = celleryHubDB->update(DELETE_LOCK_ENTRIES_QUERY, imageFQN);
37 | if (lockCleanupResult is error) {
38 | log:printError("Failed to cleanup lock rows created for image " + imageFQN, err = lockCleanupResult);
39 | } else {
40 | log:printDebug("Removed DB row used for locking image " + imageFQN);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/components/portal/src/utils/constants.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | const Constants = {
20 | Color: {
21 | SUCCESS: "#23ff5d",
22 | ERROR: "#ff443d"
23 | },
24 | Pattern: {
25 | CELLERY_ID: "[a-z0-9]+(-[a-z0-9]+)*",
26 | PARTIAL_CELLERY_ID: "[-a-z0-9]+",
27 | PARTIAL_IMAGE_VERSION: "[-.a-z0-9]+",
28 | PARTIAL_IMAGE_FQN: "((?:-?[a-z0-9]+)+)(?:/([a-z0-9]+))?[-a-z0-9]*"
29 | },
30 | Format: {
31 | DATE_TIME: "DD MMM YYYY, hh:mm:ss A"
32 | },
33 | Visibility: {
34 | PUBLIC: "PUBLIC",
35 | PRIVATE: "PRIVATE"
36 | },
37 | SortingOrder: {
38 | MOST_POPULAR: "most-popular",
39 | RECENTLY_UPDATED: "last-updated"
40 | },
41 | KeyCode: {
42 | ENTER: 13
43 | },
44 | Header: {
45 | CELLERY_HUB_CAPTCHA: "g-recaptcha-response"
46 | },
47 | ApplicationErrorCode: {
48 | ALREADY_EXISTS: 2,
49 | ALLOWED_LIMIT_EXCEEDED: 3,
50 | ENTRY_NOT_FOUND: 4
51 | },
52 | Permission: {
53 | ADMIN: "admin",
54 | PUSH: "push",
55 | PULL: "pull"
56 | },
57 | Type: {
58 | CELL: "Cell",
59 | COMPOSITE: "Composite"
60 | }
61 | };
62 |
63 | export default Constants;
64 |
--------------------------------------------------------------------------------
/components/api/core/response_handler.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | public function buildErrorResponse(int statusCode, int code, string message, string description) returns http:Response {
20 | http:Response res = new;
21 | gen:ErrorResponse errPassed = {
22 | code: code,
23 | message: message,
24 | description: description
25 | };
26 | var errJson = json.convert(errPassed);
27 | if (errJson is json) {
28 | res.setJsonPayload(errJson);
29 | res.statusCode = statusCode;
30 | } else {
31 | res = buildUnknownErrorResponse();
32 | }
33 | return res;
34 | }
35 |
36 | function buildUnknownErrorResponse() returns http:Response {
37 | http:Response res = new;
38 | json errDefault = {
39 | code: constants:API_ERROR_CODE,
40 | message: "Unexpected error occurred",
41 | description: ""
42 | };
43 | res.setPayload(errDefault);
44 | res.statusCode = http:INTERNAL_SERVER_ERROR_500;
45 | return res;
46 | }
47 |
48 | function buildSuccessResponse(json jsonResponse = null) returns http:Response {
49 | http:Response resp = new;
50 | resp.statusCode = http:OK_200;
51 | resp.setJsonPayload(untaint jsonResponse);
52 | return resp;
53 | }
54 |
--------------------------------------------------------------------------------
/components/identity-server-customization/cellery-identity-customizations/src/main/java/io/cellery/hub/identity/extension/internal/CelleryCustomizationDataHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package io.cellery.hub.identity.extension.internal;
20 |
21 | import org.wso2.carbon.registry.core.service.RegistryService;
22 | import org.wso2.carbon.user.core.service.RealmService;
23 |
24 | /**
25 | * Keep services aquired through OSGI.
26 | */
27 | public class CelleryCustomizationDataHolder {
28 |
29 | private RealmService realmService = null;
30 | private RegistryService registryService = null;
31 | private static CelleryCustomizationDataHolder instance = new CelleryCustomizationDataHolder();
32 |
33 | public static CelleryCustomizationDataHolder getInstance() {
34 |
35 | return instance;
36 | }
37 |
38 | private CelleryCustomizationDataHolder() {
39 |
40 | }
41 |
42 | public RegistryService getRegistryService() {
43 |
44 | return registryService;
45 | }
46 |
47 | public void setRegistryService(RegistryService registryService) {
48 |
49 | this.registryService = registryService;
50 | }
51 |
52 | public RealmService getRealmService() {
53 |
54 | return realmService;
55 | }
56 |
57 | public void setRealmService(RealmService realmService) {
58 |
59 | this.realmService = realmService;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/docker/identity-server/Dockerfile:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | #
3 | # Copyright 2018 WSO2, Inc. (http://wso2.com)
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License
16 | #
17 | # ------------------------------------------------------------------------
18 |
19 | FROM wso2cellery/cellery-hub-idp-base:5.8.0
20 |
21 | ARG USER_HOME=/home/wso2carbon
22 | ARG FILES=./target/files
23 | ARG AUTHENTICATION_ENDPOINT_WEBAPP=${USER_HOME}/wso2is-5.8.0/repository/deployment/server/webapps/authenticationendpoint
24 |
25 | # Copy the jar files
26 | COPY --chown=wso2carbon:wso2 ${FILES}/dropins/** ${USER_HOME}/wso2is-5.8.0/repository/components/dropins/
27 |
28 | # Copy the error pages
29 |
30 | RUN mkdir ${AUTHENTICATION_ENDPOINT_WEBAPP}
31 |
32 | RUN cd ${AUTHENTICATION_ENDPOINT_WEBAPP}; \
33 | jar -xvf ${AUTHENTICATION_ENDPOINT_WEBAPP}.war
34 |
35 | COPY --chown=wso2carbon:wso2 ${FILES}/authenticationendpoint/css/custom-common.css ${AUTHENTICATION_ENDPOINT_WEBAPP}/css/custom-common.css
36 | COPY --chown=wso2carbon:wso2 ${FILES}/authenticationendpoint/images/ ${AUTHENTICATION_ENDPOINT_WEBAPP}/images/
37 | COPY --chown=wso2carbon:wso2 ${FILES}/authenticationendpoint/cellery_error.jsp ${AUTHENTICATION_ENDPOINT_WEBAPP}/oauth2_error.jsp
38 | COPY --chown=wso2carbon:wso2 ${FILES}/authenticationendpoint/cellery_error.jsp ${AUTHENTICATION_ENDPOINT_WEBAPP}/retry.jsp
39 | COPY --chown=wso2carbon:wso2 ${FILES}/authenticationendpoint/localize/* ${AUTHENTICATION_ENDPOINT_WEBAPP}/WEB-INF/classes/org/wso2/carbon/identity/application/authentication/endpoint/i18n/
40 |
--------------------------------------------------------------------------------
/components/portal/src/components/explore/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import CustomizedTabs from "../common/CustomizedTabs";
20 | import Divider from "@material-ui/core/Divider";
21 | import Images from "./Images";
22 | import Orgs from "./Orgs";
23 | import React from "react";
24 | import Typography from "@material-ui/core/Typography";
25 | import {withStyles} from "@material-ui/core/styles";
26 | import * as PropTypes from "prop-types";
27 |
28 | const styles = (theme) => ({
29 | content: {
30 | paddingTop: theme.spacing(4)
31 | },
32 | divider: {
33 | marginBottom: theme.spacing(4)
34 | }
35 | });
36 |
37 | const Explore = (props) => {
38 | const {classes} = props;
39 | const tabs = [
40 | {
41 | label: "Images",
42 | render: () =>
43 | },
44 | {
45 | label: "Organizations",
46 | render: () =>
47 | }
48 | ];
49 | return (
50 |
51 |
52 | Explore
53 |
54 |
55 |
56 |
57 | );
58 | };
59 |
60 | Explore.propTypes = {
61 | classes: PropTypes.object.isRequired
62 | };
63 |
64 | export default withStyles(styles)(Explore);
65 |
--------------------------------------------------------------------------------
/components/docker-auth/pkg/extension/constants.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 WSO2 Inc. (http:www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http:www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package extension
20 |
21 | const userAdminRole = "admin"
22 | const userPushRole = "push"
23 |
24 | const MysqlUserEnvVar = "MYSQL_USER"
25 | const MysqlPasswordEnvVar = "MYSQL_PASSWORD"
26 | const MysqlHostEnvVar = "MYSQL_HOST"
27 | const MysqlPortEnvVar = "MYSQL_PORT"
28 | const MysqlDriver = "mysql"
29 | const DbName = "CELLERY_HUB"
30 | const IdpUsernameEnvVar = "USERNAME"
31 | const IdppasswordEnvVar = "PASSWORD"
32 |
33 | const MaxOpenConnectionsEnvVar = "MAX_OPEN_CONNECTIONS"
34 | const MaxIdleConnectionsEnvVar = "MAX_IDLE_CONNECTIONS"
35 | const ConnectionMaxLifetimeEnvVar = "MAX_LIFE_TIME"
36 |
37 | const pullAction = "pull"
38 | const pushAction = "push"
39 | const deleteAction = "delete"
40 | const publicVisibility = "PUBLIC"
41 |
42 | // db queries
43 | const getVisibilityQuery = "SELECT VISIBILITY FROM REGISTRY_ARTIFACT_IMAGE " +
44 | "INNER JOIN REGISTRY_ORGANIZATION ON REGISTRY_ORGANIZATION.ORG_NAME=REGISTRY_ARTIFACT_IMAGE.ORG_NAME " +
45 | "WHERE REGISTRY_ARTIFACT_IMAGE.IMAGE_NAME=? AND " +
46 | "REGISTRY_ORGANIZATION.ORG_NAME=? LIMIT 1"
47 | const getUserAvailabilityQuery = "SELECT 1 FROM " +
48 | "REGISTRY_ORG_USER_MAPPING " +
49 | "WHERE REGISTRY_ORG_USER_MAPPING.USER_UUID=? AND REGISTRY_ORG_USER_MAPPING.ORG_NAME=?"
50 | const getUserRoleQuery = "SELECT USER_ROLE FROM " +
51 | "REGISTRY_ORG_USER_MAPPING " +
52 | "WHERE REGISTRY_ORG_USER_MAPPING.USER_UUID=? AND REGISTRY_ORG_USER_MAPPING.ORG_NAME=?"
53 |
--------------------------------------------------------------------------------
/components/api/docker_registry/auth_token.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | import ballerina/http;
20 | import ballerina/io;
21 | import cellery_hub_api/constants;
22 |
23 | public function getTokenFromDockerAuth(string userName, string token, string registryScope) returns string | error? {
24 | log:printDebug(io:sprintf("Invoking docker auth API for get token for scope : %s", registryScope));
25 |
26 | string | error registryServiceName = http:encode(constants:DOCKER_REGISTRY_SERVICE_NAME, "utf-8");
27 |
28 | if (registryServiceName is string) {
29 | string getTokenPathParams = io:sprintf("/auth?service=%s&scope=%s", registryServiceName, registryScope);
30 | http:Client dockerAuthClient = getDockerAuthClient(userName, token);
31 | var authResponse = dockerAuthClient->get(getTokenPathParams, message = "");
32 | if (authResponse is http:Response) {
33 | var authPayload = authResponse.getJsonPayload();
34 | if (authPayload is json) {
35 | return authPayload["token"].toString();
36 | }
37 | } else {
38 | error er = error(io:sprintf("Error when calling the dockerAuthClient. %s", authResponse.reason()));
39 | return er;
40 | }
41 | } else {
42 | error er = error(io:sprintf("Error when encoding the registry service name. %s", registryServiceName.reason()));
43 | return er;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/components/api/validator/configReader.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | import ballerina/io;
20 | import ballerina/log;
21 | import ballerina/system;
22 | import ballerina/filepath;
23 | import ballerina/config;
24 | import cellery_hub_api/constants;
25 |
26 | public type Conf record { |
27 | string introspectionEp = constants:DEFAULT_IDP_ENDPOINT;
28 | string username = constants:IDP_DEFAULT_USERNAME;
29 | string password = constants:IDP_DEFAULT_PASSWORD;
30 | | };
31 |
32 | Conf config = {};
33 | boolean configLoaded = false;
34 | public function getAuthConfig() returns (Conf)|error {
35 | if configLoaded == true {
36 | return config;
37 | }
38 | log:printDebug("Started to read config file");
39 | if (config:getAsString(constants:IDP_INTROSPCET_VAR) != "" && config:getAsString(constants:IDP_USERNAME_VAR) != "" &&
40 | config:getAsString(constants:IDP_PASSWORD_VAR) != "") {
41 | config = {
42 | introspectionEp:config:getAsString(constants:IDP_ENDPOINT_VAR) + config:getAsString
43 | (constants:IDP_INTROSPCET_VAR),
44 | username:config:getAsString(constants:IDP_USERNAME_VAR),
45 | password:config:getAsString(constants:IDP_PASSWORD_VAR)
46 | };
47 | } else {
48 | log:printInfo("Could not resolve the values from configs. Hence using the default values");
49 | }
50 | configLoaded = true;
51 | return config;
52 | }
53 |
--------------------------------------------------------------------------------
/components/docker-auth/test/data.sql:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | #
3 | # Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License
16 | #
17 | # ------------------------------------------------------------------------
18 |
19 | USE CELLERY_HUB;
20 | INSERT INTO `REGISTRY_ORGANIZATION` (ORG_NAME, DESCRIPTION, WEBSITE_URL, DEFAULT_IMAGE_VISIBILITY, FIRST_AUTHOR, CREATED_DATE) VALUES ('cellery','ABC is my first org','abc.com','private','unknown','2019-05-27 14:58:47');
21 | INSERT INTO `REGISTRY_ORGANIZATION` (ORG_NAME, DESCRIPTION, WEBSITE_URL, DEFAULT_IMAGE_VISIBILITY, FIRST_AUTHOR, CREATED_DATE) VALUES ('is','ABC is my first org','pqr.com','private','unknown','2019-05-27 14:58:47');
22 | INSERT INTO `REGISTRY_ORG_USER_MAPPING` (USER_UUID, ORG_NAME, USER_ROLE, CREATED_DATE) VALUES ('wso2.com','cellery','push','2019-04-06 00:00:00');
23 | INSERT INTO `REGISTRY_ORG_USER_MAPPING` (USER_UUID, ORG_NAME, USER_ROLE, CREATED_DATE) VALUES ('admin.com','cellery','admin','2019-04-06 00:00:00');
24 | INSERT INTO `REGISTRY_ORG_USER_MAPPING` (USER_UUID, ORG_NAME, USER_ROLE, CREATED_DATE) VALUES ('other.com','is','pull','2019-04-06 00:00:00');
25 | INSERT INTO `REGISTRY_ARTIFACT_IMAGE` (ARTIFACT_IMAGE_ID, ORG_NAME, IMAGE_NAME, DESCRIPTION, FIRST_AUTHOR, VISIBILITY) VALUES ('1','cellery','image','Sample','unkown','PUBLIC');
26 | INSERT INTO `REGISTRY_ARTIFACT_IMAGE` (ARTIFACT_IMAGE_ID, ORG_NAME, IMAGE_NAME, DESCRIPTION, FIRST_AUTHOR, VISIBILITY) VALUES ('2','cellery','newImage','Sample','www.dockehub.com','PRIVATE');
27 | INSERT INTO `REGISTRY_ARTIFACT_IMAGE` (ARTIFACT_IMAGE_ID, ORG_NAME, IMAGE_NAME, DESCRIPTION, FIRST_AUTHOR, VISIBILITY) VALUES ('3','is','pqr','Sample','www.dockehub.com','PRIVATE');
28 |
--------------------------------------------------------------------------------
/components/docker-auth/cmd/authz/authorization.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 WSO2 Inc. (http:www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http:www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package main
20 |
21 | import (
22 | "fmt"
23 |
24 | "github.com/cesanta/docker_auth/auth_server/api"
25 | "go.uber.org/zap"
26 |
27 | "github.com/cellery-io/cellery-hub/components/docker-auth/pkg/auth"
28 | "github.com/cellery-io/cellery-hub/components/docker-auth/pkg/db"
29 | "github.com/cellery-io/cellery-hub/components/docker-auth/pkg/extension"
30 | )
31 |
32 | var logger *zap.SugaredLogger
33 |
34 | type PluginAuthz struct {
35 | }
36 |
37 | func (*PluginAuthz) Stop() {
38 | }
39 |
40 | func (*PluginAuthz) Name() string {
41 | return "plugin authz"
42 | }
43 |
44 | func (c *PluginAuthz) Authorize(ai *api.AuthRequestInfo) ([]string, error) {
45 | if logger == nil {
46 | logger = extension.NewLogger()
47 | }
48 | return doAuthorize(ai, logger)
49 | }
50 |
51 | var Authz PluginAuthz
52 |
53 | func doAuthorize(ai *api.AuthRequestInfo, logger *zap.SugaredLogger) ([]string, error) {
54 | execId, err := extension.GetExecID(logger)
55 | if err != nil {
56 | return nil, fmt.Errorf("error in generating the execId : %s", err)
57 | }
58 | logger.Debugf("Authorization logic reached. User will be authorized")
59 | dbConnectionPool, err := db.GetDbConnectionPool(logger)
60 | if err != nil {
61 | return nil, fmt.Errorf("error while establishing database connection pool: %v", err)
62 | }
63 | authorized, err := auth.Authorize(dbConnectionPool, ai, logger, execId)
64 | if err != nil {
65 | return nil, fmt.Errorf("error while executing authorization logic: %v", err)
66 | }
67 | if !authorized {
68 | logger.Debugf("[%s] User : %s is unauthorized for %s actions", execId, ai.Account, ai.Actions)
69 | return nil, nil
70 | } else {
71 | logger.Debugf("[%s] User : %s is authorized for %s actions", execId, ai.Account, ai.Actions)
72 | return ai.Actions, nil
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/components/portal/node-server/serve.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | const path = require("path");
20 | const fs = require("fs");
21 | const https = require("https");
22 | const express = require("express");
23 | const fallback = require("express-history-api-fallback");
24 |
25 | let app = express();
26 | const webPortalPort = process.env.PORTAL_PORT || 3000;
27 |
28 | const configRoot = path.join(__dirname, "/config");
29 | const portalConfigFile = `${configRoot}/portal.json`;
30 | console.log(`Using Portal Configuration from ${portalConfigFile} file`);
31 |
32 | let portalConfig;
33 | const loadPortalConfig = () => {
34 | portalConfig = fs.readFileSync(`${portalConfigFile}`, "utf8");
35 | console.log("Loaded new Portal Configuration");
36 | };
37 | loadPortalConfig();
38 |
39 | // Watching for config changes
40 | fs.watch(configRoot, null, () => {
41 | loadPortalConfig();
42 | });
43 |
44 | // REST API for configurations
45 | app.get("/config", (req, res) => {
46 | res.set("Content-Type", "application/json");
47 | res.send(portalConfig);
48 | });
49 |
50 | if (process.env.APP_ENV !== "DEV") {
51 | const appRoot = path.join(__dirname, "/public");
52 | console.log(`Using App from ${appRoot} directory`);
53 |
54 | // Serving the React App
55 | app.use(express.static(appRoot));
56 | app.use(fallback("index.html", {
57 | root: appRoot
58 | }));
59 |
60 | // Creating an HTTPS server for production
61 | app = https.createServer({
62 | key: fs.readFileSync(process.env.PORTAL_PRIVATE_KEY),
63 | cert: fs.readFileSync(process.env.PORTAL_CERT)
64 | }, app);
65 | } else {
66 | console.log("Serving Only the Hub Portal Configuration");
67 | }
68 |
69 | const server = app.listen(webPortalPort, () => {
70 | const host = server.address().address;
71 | const port = server.address().port;
72 |
73 | console.log("Cellery Hub Portal listening at http://%s:%s", host, port);
74 | });
75 |
--------------------------------------------------------------------------------
/components/proxy/docker_registry/registry.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | import ballerina/io;
20 | import ballerina/config;
21 | import ballerina/http;
22 |
23 | http:Client dockerRegistryClientEP = new(config:getAsString("docker.registry.url"), config = {
24 | secureSocket: {
25 | trustedCertFile: config:getAsString("security.trustedcertsfile"),
26 | verifyHostname: false
27 | }
28 |
29 | });
30 |
31 | # Forward a request to the Docker Rgistry.
32 | #
33 | # + req - The request to be forwared to the docker registry
34 | # + return - The response received from the registry
35 | public function forwardRequest(http:Request req) returns (http:Response|error) {
36 | return dockerRegistryClientEP->forward(untaint req.rawPath, req);
37 | }
38 |
39 | # Pull a file layer from the Docker Registry.
40 | #
41 | # + repository - The Docker Image Repository name
42 | # + fileLayer - Docker File Layer to be pulled
43 | # + jwtToken - The JWT token that should be used
44 | # + return - Docker file layer bytes
45 | public function pullDockerFileLayer(string repository, string fileLayer, string jwtToken) returns (byte[]|error) {
46 | http:Request dockerRegistryRequest = new;
47 | dockerRegistryRequest.addHeader("Authorization", "Bearer " + jwtToken);
48 | var response = check dockerRegistryClientEP->get(io:sprintf("/v2/%s/blobs/%s", repository, fileLayer),
49 | message = dockerRegistryRequest);
50 | if (response.statusCode >= 200 && response.statusCode < 400) {
51 | return response.getBinaryPayload();
52 | } else if (response.statusCode == 401) {
53 | error err = error("unauthorized to pull docker file layer " + fileLayer);
54 | return err;
55 | } else {
56 | error err = error(io:sprintf("failed to pull docker file layer %s with status code %s", fileLayer,
57 | response.statusCode));
58 | return err;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 | > Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.
3 |
4 | ## Goals
5 | > Describe the solutions that this feature/fix will introduce to resolve the problems described above
6 |
7 | ## Approach
8 | > Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.
9 |
10 | ## User stories
11 | > Summary of user stories addressed by this change>
12 |
13 | ## Release note
14 | > Brief description of the new feature or bug fix as it will appear in the release notes
15 |
16 | ## Documentation
17 | > Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact
18 |
19 | ## Training
20 | > Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable
21 |
22 | ## Certification
23 | > Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.
24 |
25 | ## Marketing
26 | > Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable
27 |
28 | ## Automation tests
29 | - Unit tests
30 | > Code coverage information
31 | - Integration tests
32 | > Details about the test cases and coverage
33 |
34 | ## Security checks
35 | - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no
36 | - Ran FindSecurityBugs plugin and verified report? yes/no
37 | - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no
38 |
39 | ## Samples
40 | > Provide high-level details about the samples related to this feature
41 |
42 | ## Related PRs
43 | > List any other related PRs
44 |
45 | ## Migrations (if applicable)
46 | > Describe migration steps and platforms on which migration has been tested
47 |
48 | ## Test environment
49 | > List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested
50 |
51 | ## Learning
52 | > Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.
--------------------------------------------------------------------------------
/components/portal/src/components/common/error/ErrorBoundary.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from "react";
18 | import UnknownError from "./UnknownError";
19 | import * as PropTypes from "prop-types";
20 |
21 | /* eslint no-console: ["off"] */
22 |
23 | /**
24 | * Error Boundary to catch error in React Components.
25 | * This Component can be used to wrap areas of the React App and catch any errors that occur inside them.
26 | *
27 | * Example:- A graph can be wrapped and the title can be set to "Invalid Data" to make sure that the users sees
28 | * this message instead of a blank screen if an error occurs.
29 | *
30 | * This will not affect the dev servers and the errors will still be shown.
31 | *
32 | * @returns {React.Component} Error Boundary React Component
33 | */
34 | class ErrorBoundary extends React.Component {
35 |
36 | constructor(props) {
37 | super(props);
38 |
39 | this.state = {
40 | hasError: false
41 | };
42 | }
43 |
44 | /**
45 | * Derive a suitable state from the error if any error occurs.
46 | *
47 | * @param {Error} error The error that occurred
48 | * @returns {Object} New state
49 | */
50 | static getDerivedStateFromError = (error) => {
51 | console.error(error);
52 | return {
53 | hasError: true
54 | };
55 | };
56 |
57 | render = () => {
58 | const {children, title, description, showNavigationButtons} = this.props;
59 | const {hasError} = this.state;
60 |
61 | let content;
62 | if (hasError) {
63 | content = (
64 |
65 | );
66 | } else {
67 | content = children;
68 | }
69 | return content;
70 | };
71 |
72 | }
73 |
74 | ErrorBoundary.propTypes = {
75 | children: PropTypes.any.isRequired,
76 | title: PropTypes.string,
77 | description: PropTypes.string,
78 | showNavigationButtons: PropTypes.bool
79 | };
80 |
81 | export default ErrorBoundary;
82 |
--------------------------------------------------------------------------------
/components/portal/src/components/appLayout/ButtonAppBarCollapse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import IconButton from "@material-ui/core/IconButton";
20 | import Menu from "@material-ui/core/Menu";
21 | import MenuIcon from "@material-ui/icons/Menu";
22 | import React from "react";
23 | import {withStyles} from "@material-ui/core/styles";
24 | import * as PropTypes from "prop-types";
25 |
26 | const styles = (theme) => ({
27 | buttonCollapse: {
28 | [theme.breakpoints.up("md")]: {
29 | display: "none"
30 | },
31 | margin: 10,
32 | boxShadow: "none"
33 | }
34 | });
35 |
36 | class ButtonAppBarCollapse extends React.Component {
37 |
38 | constructor(props) {
39 | super(props);
40 | this.state = {
41 | anchorEl: null
42 | };
43 | this.handleMenu = this.handleMenu.bind(this);
44 | }
45 |
46 | handleMenu = (event) => {
47 | this.setState({anchorEl: event.currentTarget});
48 | };
49 |
50 | handleClose = () => {
51 | this.setState({anchorEl: null});
52 | };
53 |
54 | render() {
55 | const {classes, children} = this.props;
56 | const {anchorEl} = this.state;
57 | const open = Boolean(anchorEl);
58 |
59 | return (
60 |
61 |
62 |
63 |
64 |
79 |
80 | );
81 | }
82 |
83 | }
84 |
85 | ButtonAppBarCollapse.propTypes = {
86 | classes: PropTypes.object.isRequired,
87 | children: PropTypes.any.isRequired
88 |
89 | };
90 |
91 | export default withStyles(styles)(ButtonAppBarCollapse);
92 |
--------------------------------------------------------------------------------
/components/portal/src/components/appLayout/Header.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import AppBar from "@material-ui/core/AppBar";
20 | import CelleryLogo from "../../img/celleryLogo.svg";
21 | import Container from "@material-ui/core/Container";
22 | import NavBar from "./NavBar";
23 | import React from "react";
24 | import Toolbar from "@material-ui/core/Toolbar";
25 | import {withRouter} from "react-router-dom";
26 | import {withStyles} from "@material-ui/core/styles";
27 | import * as PropTypes from "prop-types";
28 |
29 | const styles = (theme) => ({
30 | appbar: {
31 | backgroundColor: "#ffffff",
32 | color: theme.palette.primary.main,
33 | boxShadow: "none"
34 | },
35 | headerLogo: {
36 | flexGrow: 1
37 | },
38 | logo: {
39 | fontSize: 32,
40 | fontWeight: 400,
41 | color: "#43AB00",
42 | cursor: "pointer"
43 | },
44 | celleryLogo: {
45 | height: 40,
46 | verticalAlign: "middle",
47 | paddingRight: 2
48 | },
49 | toolbar: {
50 | paddingLeft: 0,
51 | paddingRight: 0
52 | },
53 | headerContent: {
54 | borderBottom: "1px solid",
55 | borderBottomColor: theme.palette.primary.main
56 | }
57 | });
58 |
59 | const Header = ({classes, history}) => (
60 |
61 |
62 |
63 |
64 |
65 |
66 |
history.push("/")}>
67 |
68 | hub
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | );
78 |
79 | Header.propTypes = {
80 | classes: PropTypes.object.isRequired,
81 | history: PropTypes.shape({
82 | push: PropTypes.func.isRequired
83 | })
84 | };
85 |
86 | export default withStyles(styles)(withRouter(Header));
87 |
--------------------------------------------------------------------------------
/components/portal/src/utils/common/notificationUtils.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import {StateHolder} from "../../components/common/state";
20 |
21 | class NotificationUtils {
22 |
23 | static Levels = {
24 | INFO: "INFO",
25 | WARNING: "WARNING",
26 | ERROR: "ERROR"
27 | };
28 |
29 | /**
30 | * Show the loading overlay.
31 | *
32 | * @param {string} message The message to be shown in the loading overlay
33 | * @param {StateHolder} globalState The global state provided to the current component
34 | */
35 | static showLoadingOverlay = (message, globalState) => {
36 | const prevState = globalState.get(StateHolder.LOADING_STATE);
37 | globalState.set(StateHolder.LOADING_STATE, {
38 | loadingOverlayCount: prevState.loadingOverlayCount + 1,
39 | message: message
40 | });
41 | };
42 |
43 | /**
44 | * Hide the loading overlay.
45 | *
46 | * @param {StateHolder} globalState The global state provided to the current component
47 | */
48 | static hideLoadingOverlay = (globalState) => {
49 | const prevState = globalState.get(StateHolder.LOADING_STATE);
50 | globalState.set(StateHolder.LOADING_STATE, {
51 | loadingOverlayCount: prevState.loadingOverlayCount === 0 ? 0 : prevState.loadingOverlayCount - 1,
52 | message: null
53 | });
54 | };
55 |
56 | /**
57 | * Show a notification to the user.
58 | *
59 | * @param {string} message The message to be shown in the notification
60 | * @param {string} level The notification level
61 | * @param {StateHolder} globalState The global state provided to the current component
62 | */
63 | static showNotification = (message, level, globalState) => {
64 | globalState.set(StateHolder.NOTIFICATION_STATE, {
65 | isOpen: true,
66 | message: message,
67 | notificationLevel: level
68 | });
69 | };
70 |
71 | /**
72 | * Close the notification shown to the user.
73 | *
74 | * @param {StateHolder} globalState The global state provided to the current component
75 | */
76 | static closeNotification = (globalState) => {
77 | globalState.set(StateHolder.NOTIFICATION_STATE, {
78 | ...globalState.get(StateHolder.NOTIFICATION_STATE),
79 | isOpen: false
80 | });
81 | };
82 |
83 | }
84 |
85 | export default NotificationUtils;
86 |
--------------------------------------------------------------------------------
/components/portal/src/components/common/Description.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import DescriptionOutlined from "@material-ui/icons/DescriptionOutlined";
20 | import Grid from "@material-ui/core/Grid";
21 | import Markdown from "react-markdown";
22 | import React from "react";
23 | import Typography from "@material-ui/core/Typography";
24 | import {withRouter} from "react-router-dom";
25 | import {withStyles} from "@material-ui/core/styles";
26 | import withGlobalState, {StateHolder} from "./state/index";
27 | import * as PropTypes from "prop-types";
28 |
29 | const styles = (theme) => ({
30 | content: {
31 | paddingTop: theme.spacing(4)
32 | },
33 | noDescriptionMsgContainer: {
34 | textAlign: "center",
35 | paddingTop: theme.spacing(6),
36 | paddingBottom: theme.spacing(4)
37 | },
38 | descriptionIcon: {
39 | color: "#a0a0a0"
40 | },
41 | noDescriptionMsg: {
42 | fontWeight: 500,
43 | color: "#a0a0a0",
44 | paddingTop: theme.spacing(1)
45 | }
46 | });
47 |
48 | const VersionList = (props) => {
49 | const {classes, data} = props;
50 |
51 | return (
52 |
74 | );
75 | };
76 |
77 | VersionList.propTypes = {
78 | data: PropTypes.string,
79 | classes: PropTypes.object.isRequired,
80 | globalState: PropTypes.instanceOf(StateHolder).isRequired
81 | };
82 |
83 | export default withStyles(styles)(withRouter(withGlobalState(VersionList)));
84 |
--------------------------------------------------------------------------------
/components/portal/src/components/sdk/SignInFailure.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import CelleryCmd from "../../img/celleryCmd.png";
20 | import ErrorOutlineRounded from "@material-ui/icons/ErrorOutlineRounded";
21 | import Grid from "@material-ui/core/Grid";
22 | import React from "react";
23 | import Typography from "@material-ui/core/Typography";
24 | import {withStyles} from "@material-ui/core/styles";
25 | import withGlobalState, {StateHolder} from "../common/state";
26 | import * as PropTypes from "prop-types";
27 |
28 | const styles = (theme) => ({
29 | content: {
30 | paddingTop: theme.spacing(4)
31 | },
32 | success: {
33 | paddingTop: theme.spacing(2),
34 | paddingBottom: theme.spacing(4)
35 | },
36 | gotoHub: {
37 | fontWeight: 400,
38 | paddingTop: theme.spacing(2),
39 | color: "#464646",
40 | textAlign: "center"
41 | },
42 | hubUrl: {
43 | color: "#464646",
44 | textDecoration: "underline"
45 | },
46 | celleryCmd: {
47 | height: 85,
48 | paddingTop: theme.spacing(2)
49 | },
50 | error: {
51 | paddingTop: theme.spacing(2),
52 | color: "#e74c3c",
53 | fontSize: "3.8rem"
54 | },
55 | nextTitle: {
56 | color: "#464646"
57 | }
58 | });
59 |
60 | const SignInFailure = (props) => {
61 | const {classes} = props;
62 | return (
63 |
64 |
65 |
66 |
67 | Authentication failure!
68 |
69 | What to do next?
70 |
71 |
72 |
73 | Go back to your terminal to know more information about the error and try login again.
74 |
75 |
76 |
77 |
78 |
79 | );
80 | };
81 |
82 | SignInFailure.propTypes = {
83 | classes: PropTypes.object.isRequired,
84 | globalState: PropTypes.instanceOf(StateHolder).isRequired
85 | };
86 |
87 | export default withStyles(styles)(withGlobalState(SignInFailure));
88 |
--------------------------------------------------------------------------------
/docker/identity-server/resources/authenticationendpoint/images/logo-inverse.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
44 |
--------------------------------------------------------------------------------
/components/proxy/database/queries.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | const string LOCK_QUERY = "INSERT INTO REGISTRY_ARTIFACT_LOCK(ARTIFACT_NAME, LOCK_COUNT) VALUES (?, 1)
20 | ON DUPLICATE KEY UPDATE LOCK_COUNT = LOCK_COUNT + 1";
21 | const string DELETE_LOCK_ENTRIES_QUERY = "DELETE FROM REGISTRY_ARTIFACT_LOCK WHERE ARTIFACT_NAME = ?";
22 |
23 | const string GET_ARTIFACT_IMAGE_ID_QUERY = "SELECT ARTIFACT_IMAGE_ID FROM REGISTRY_ARTIFACT_IMAGE
24 | WHERE ORG_NAME = ? AND IMAGE_NAME = ? FOR UPDATE";
25 | const string UPDATE_PULL_COUNT_QUERY = "UPDATE REGISTRY_ARTIFACT SET PULL_COUNT = PULL_COUNT + 1,
26 | UPDATED_DATE = UPDATED_DATE WHERE ARTIFACT_IMAGE_ID = ? AND VERSION = ?";
27 | const string INSERT_ARTIFACT_IMAGE_QUERY = "INSERT INTO REGISTRY_ARTIFACT_IMAGE(ARTIFACT_IMAGE_ID, ORG_NAME,
28 | IMAGE_NAME, FIRST_AUTHOR, VISIBILITY) VALUES (?, ?, ?, ?, ?)";
29 |
30 | const string GET_ORG_DEFAULT_IMAGE_VISIBILITY_QUERY = "SELECT DEFAULT_IMAGE_VISIBILITY
31 | FROM REGISTRY_ORGANIZATION WHERE ORG_NAME = ? FOR UPDATE";
32 |
33 | const string GET_ARTIFACT_ID_QUERY = "SELECT ARTIFACT_ID FROM REGISTRY_ARTIFACT
34 | WHERE ARTIFACT_IMAGE_ID = ? AND VERSION = ? FOR UPDATE";
35 | const string INSERT_REGISTRY_ARTIFACT_QUERY = "INSERT INTO REGISTRY_ARTIFACT(ARTIFACT_ID, ARTIFACT_IMAGE_ID, VERSION,
36 | PUSH_COUNT, LAST_AUTHOR, FIRST_AUTHOR, METADATA, STATEFUL)
37 | VALUES (?, ?, ?, 1, ?, ?, ?, ?)";
38 | const string UPDATE_REGISTRY_ARTIFACT_QUERY = "UPDATE REGISTRY_ARTIFACT SET PUSH_COUNT = PUSH_COUNT + 1,
39 | LAST_AUTHOR = ?, METADATA = ?, STATEFUL = ? WHERE ARTIFACT_ID = ?
40 | AND VERSION = ?";
41 |
42 | const string INSERT_REGISTRY_ARTIFACT_LABELS_QUERY = "INSERT INTO REGISTRY_ARTIFACT_LABEL(ARTIFACT_ID, LABEL_KEY,
43 | LABEL_VALUE) VALUES (?, ?, ?)";
44 | const string DELETE_REGISTRY_ARTIFACT_LABELS_QUERY = "DELETE FROM REGISTRY_ARTIFACT_LABEL WHERE ARTIFACT_ID = ?";
45 |
46 | const string INSERT_REGISTRY_ARTIFACT_INGRESSES_QUERY = "INSERT INTO REGISTRY_ARTIFACT_INGRESS(ARTIFACT_ID,
47 | INGRESS_TYPE) VALUES (?, ?)";
48 | const string DELETE_REGISTRY_ARTIFACT_INGRESSES_QUERY = "DELETE FROM REGISTRY_ARTIFACT_INGRESS WHERE ARTIFACT_ID = ?";
49 |
--------------------------------------------------------------------------------
/components/portal/src/utils/api/authUtils.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | /* eslint camelcase: ["off"] */
20 |
21 | import AuthUtils from "./authUtils";
22 | import HttpUtils from "./httpUtils";
23 | import {StateHolder} from "../../components/common/state";
24 |
25 | describe("AuthUtils", () => {
26 | const username = "User1";
27 | const loggedInUser = {
28 | username: username,
29 | tokens: {
30 | accessToken: "12345",
31 | idToken: "54321"
32 | }
33 | };
34 | afterEach(() => {
35 | localStorage.removeItem(StateHolder.USER);
36 | });
37 |
38 | describe("updateUser()", () => {
39 | it("should set the username provided", () => {
40 | const stateHolder = new StateHolder();
41 | const spy = jest.spyOn(stateHolder, "set");
42 | AuthUtils.updateUser(loggedInUser, stateHolder);
43 |
44 | expect(spy).toHaveBeenCalledTimes(1);
45 | expect(spy).toHaveBeenCalledWith(StateHolder.USER, loggedInUser);
46 | expect(localStorage.getItem(StateHolder.USER)).toBe(JSON.stringify(loggedInUser));
47 | });
48 | });
49 |
50 | describe("signOut()", () => {
51 | it("should unset the user in the state", async () => {
52 | const stateHolder = new StateHolder();
53 | localStorage.setItem(StateHolder.USER, JSON.stringify(loggedInUser));
54 | stateHolder.state[StateHolder.USER] = {
55 | value: {...loggedInUser},
56 | listeners: []
57 | };
58 | stateHolder.state[StateHolder.CONFIG] = {
59 | value: {
60 | hubApiUrl: "http://api.hub.cellery.io",
61 | idp: {
62 | url: "https://idp.hub.cellery.io",
63 | clientId: "testclientid"
64 | }
65 | },
66 | listener: []
67 | };
68 | jest.spyOn(window.location, "assign").mockImplementation((location) => {
69 | const params = {
70 | id_token_hint: "54321",
71 | post_logout_redirect_uri: `${window.location.origin}/`
72 | };
73 | const endpoint = `${stateHolder.get(StateHolder.CONFIG).idp.url}${AuthUtils.LOGOUT_ENDPOINT}`;
74 | expect(location).toEqual(`${endpoint}${HttpUtils.generateQueryParamString(params)}`);
75 | });
76 | await AuthUtils.signOut(stateHolder);
77 | expect(localStorage.getItem(StateHolder.USER)).toBeNull();
78 | window.location.assign.mockClear();
79 | });
80 | });
81 |
82 | describe("getAuthenticatedUser()", () => {
83 | localStorage.setItem(StateHolder.USER, JSON.stringify(loggedInUser));
84 | const user = AuthUtils.getAuthenticatedUser();
85 |
86 | expect(user).toEqual({...user});
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/components/docker-auth/cmd/authn/authentication.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 WSO2 Inc. (http:www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http:www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package main
20 |
21 | import (
22 | "fmt"
23 | "strconv"
24 | "strings"
25 |
26 | "github.com/cesanta/docker_auth/auth_server/api"
27 | "go.uber.org/zap"
28 |
29 | "github.com/cellery-io/cellery-hub/components/docker-auth/pkg/auth"
30 | "github.com/cellery-io/cellery-hub/components/docker-auth/pkg/extension"
31 | )
32 |
33 | var logger *zap.SugaredLogger
34 |
35 | type PluginAuthn struct {
36 | }
37 |
38 | func (*PluginAuthn) Authenticate(user string, password api.PasswordString) (bool, api.Labels, error) {
39 | if logger == nil {
40 | logger = extension.NewLogger()
41 | }
42 | return doAuthentication(user, string(password), logger)
43 | }
44 |
45 | func (*PluginAuthn) Stop() {
46 | }
47 |
48 | func (*PluginAuthn) Name() string {
49 | return "plugin auth"
50 | }
51 |
52 | var Authn PluginAuthn
53 |
54 | func doAuthentication(user, incomingToken string, logger *zap.SugaredLogger) (bool, api.Labels, error) {
55 | execId, err := extension.GetExecID(logger)
56 | if err != nil {
57 | return false, nil, fmt.Errorf("error in generating the execId : %s", err)
58 | }
59 |
60 | logger.Debugf("[%s] Username %q and password received from CLI", execId, user)
61 |
62 | tokenArray := strings.Split(incomingToken, ":")
63 | token := tokenArray[0]
64 |
65 | isPing := len(tokenArray) > 1 && tokenArray[1] == "ping"
66 | if isPing {
67 | logger.Debugf("[%s] Ping request received", execId)
68 | }
69 |
70 | // This logic is to allow users to pull public images without credentials. So that only if credentials are
71 | // present, IDP is called. If credentials are not present, through authorization logic image visibility
72 | // will be evaluated.
73 | var isAuthenticated bool
74 | if user != "" && token != "" {
75 | isAuthenticated, err = auth.Authenticate(user, token, logger, execId)
76 | if err != nil {
77 | return false, nil, fmt.Errorf("error while authenticating %v", err)
78 | }
79 | }
80 | if !isAuthenticated {
81 | logger.Debugf("[%s] User access token failed to authenticate. Evaluating ping", execId)
82 | if isPing {
83 | return false, nil, fmt.Errorf("since this is a ping request, exiting with auth fail status " +
84 | "without passing to authorization filter")
85 | } else {
86 | logger.Debugf("[%s] Failed authentication. But passing to authorization filter", execId)
87 | return true, makeAuthenticationLabel(false), nil
88 | }
89 | } else {
90 | logger.Debugf("[%s] User successfully authenticated by validating token", execId)
91 | return true, makeAuthenticationLabel(true), nil
92 | }
93 | }
94 |
95 | func makeAuthenticationLabel(isAuthenticated bool) api.Labels {
96 | authResultString := strconv.FormatBool(isAuthenticated)
97 | authLabels := api.Labels{}
98 | authLabels["isAuthSuccess"] = []string{authResultString}
99 | return authLabels
100 | }
101 |
--------------------------------------------------------------------------------
/components/portal/src/components/sdk/SignInSuccess.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import CelleryCmd from "../../img/celleryCmd.png";
20 | import CheckCircleOutline from "@material-ui/icons/CheckCircleOutlineRounded";
21 | import Grid from "@material-ui/core/Grid";
22 | import Link from "@material-ui/core/Link";
23 | import React from "react";
24 | import Typography from "@material-ui/core/Typography";
25 | import {withStyles} from "@material-ui/core/styles";
26 | import withGlobalState, {StateHolder} from "../common/state";
27 | import * as PropTypes from "prop-types";
28 |
29 | const styles = (theme) => ({
30 | content: {
31 | paddingTop: theme.spacing(4)
32 | },
33 | success: {
34 | paddingTop: theme.spacing(2),
35 | paddingBottom: theme.spacing(4)
36 | },
37 | gotoHub: {
38 | fontWeight: 400,
39 | paddingTop: theme.spacing(2),
40 | color: "#464646",
41 | textAlign: "center"
42 | },
43 | hubUrl: {
44 | color: "#464646",
45 | textDecoration: "underline"
46 | },
47 | celleryCmd: {
48 | height: 85,
49 | paddingTop: theme.spacing(2)
50 | },
51 | check: {
52 | paddingTop: theme.spacing(2),
53 | color: theme.palette.primary.main,
54 | fontSize: "3.3rem"
55 | },
56 | nextTitle: {
57 | color: "#464646"
58 | }
59 | });
60 |
61 | const SignInSuccess = (props) => {
62 | const {classes, globalState} = props;
63 | const hubPublicUrl = globalState.get(StateHolder.CONFIG).hubPublicUrl;
64 | return (
65 |
66 |
67 |
68 |
69 | You are now authenticated with Cellery SDK!
70 |
71 | What's next?
72 |
73 |
74 | You may close this window and go back to your terminal to push your Cell images
75 |
76 | or
77 | You can go to
78 | Cellery Hub to manage your organizations and Cell images.
79 |
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
87 | SignInSuccess.propTypes = {
88 | classes: PropTypes.object.isRequired,
89 | globalState: PropTypes.instanceOf(StateHolder).isRequired
90 | };
91 |
92 | export default withStyles(styles)(withGlobalState(SignInSuccess));
93 |
--------------------------------------------------------------------------------
/components/api/constants/constants.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | public const string APPLICATION_URL_ENCODED_CONTENT_TYPE = "application/x-www-form-urlencoded";
20 |
21 | public const string AUTHENTICATED_USER = "x-cellery-hub-user";
22 | public const string CONSTRUCTED_TOKEN = "x-cellery-hub-user-token";
23 | public const string G_CAPTCHA_RESPONSE = "g-recaptcha-response";
24 | public const string SET_COOKIE_HEADER = "Set-Cookie";
25 |
26 | public const int API_ERROR_CODE = 1;
27 | public const int ENTRY_ALREADY_EXISTING_ERROR_CODE = 2;
28 | public const int ALLOWED_LIMIT_EXCEEDED_ERROR_CODE = 3;
29 | public const int ENTRY_NOT_FOUND_ERROR_CODE = 4;
30 | public const int ACTION_NOT_ALLOWED_ERROR_CODE = 5;
31 |
32 | public const string VALIDATE_USER = "validateUser";
33 | public const string OFFSET = "offset";
34 | public const string RESULT_LIMIT = "resultLimit";
35 | public const string ARTIFACT_VERSION = "artifactVersion";
36 | public const string ORG_NAME = "orgName";
37 | public const string IMAGE_NAME = "imageName";
38 | public const string ORDER_BY = "orderBy";
39 |
40 | public const string IDP_ENDPOINT_VAR = "idp.endpoint";
41 | public const string IDP_INTROSPCET_VAR = "idp.introspection.endpoint";
42 | public const string IDP_USERNAME_VAR = "idp.username";
43 | public const string IDP_PASSWORD_VAR = "idp.password";
44 |
45 | public const string DEFAULT_IDP_ENDPOINT = "https://localhost:9443/oauth2/introspect";
46 | public const string IDP_DEFAULT_PASSWORD = "admin";
47 | public const string IDP_DEFAULT_USERNAME = "admin";
48 |
49 | public const string AUTHORIZATION_HEADER = "Authorization";
50 | public const string COOKIE_HEADER = "Cookie";
51 | public const string BEARER_HEADER = "Bearer";
52 | public const string TOKEN_COOKIE_KEY = "chpat";
53 |
54 | public const string ROLE_ADMIN = "admin";
55 | public const string ROLE_PUSH = "push";
56 | public const string DEFAULT_IMAGE_VISIBILITY = "PUBLIC";
57 | public const string PULL_COUNT = "PULL_COUNT";
58 | public const string UPDATED_DATE = "UPDATED_DATE";
59 |
60 | public const string DELETE_ACTION = "delete";
61 | public const string PULL_ACTION = "pull";
62 |
63 | public const string TOKEN_CACHE_EXPIRY_VAR = "token.cache.expiry";
64 | public const string TOKEN_CACHE_CAPACITY_VAR = "token.cache.capacity";
65 | public const string USERINFO_CACHE_EXPIRY_VAR = "userinfo.cache.expiry";
66 | public const string USERINFO_CACHE_CAPACITY_VAR = "userinfo.cache.capacity";
67 |
68 | public const string DOCKER_REGISTRY_SERVICE_NAME = "Docker registry";
69 | public const string DOCKER_REGISTRY_REPOSITORIES_FILEPATH = "/var/lib/registry/docker/registry/v2/repositories";
70 | public const string REGISTRY_RESPONSE_ERRORS_FIELD = "errors";
71 | public const string REGISTRY_RESPONSE_DETAIL_FIELD = "detail";
72 | public const string REGISTRY_RESPONSE_TYPE_FIELD = "Type";
73 | public const string REGISTRY_RESPONSE_NAME_FIELD = "Name";
74 | public const string REGISTRY_RESPONSE_ACTION_FIELD = "Action";
75 | public const string REGISTRY_DIGEST_HEADER = "Docker-Content-Digest";
76 |
--------------------------------------------------------------------------------
/components/docker-auth/pkg/db/connection.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 WSO2 Inc. (http:www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http:www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package db
20 |
21 | import (
22 | "database/sql"
23 | "fmt"
24 | "os"
25 | "strconv"
26 | "time"
27 |
28 | _ "github.com/go-sql-driver/mysql"
29 | "go.uber.org/zap"
30 |
31 | "github.com/cellery-io/cellery-hub/components/docker-auth/pkg/extension"
32 | )
33 |
34 | func GetDbConnectionPool(logger *zap.SugaredLogger) (*sql.DB, error) {
35 | dbDriver := extension.MysqlDriver
36 | dbUser := os.Getenv(extension.MysqlUserEnvVar)
37 | dbPass := os.Getenv(extension.MysqlPasswordEnvVar)
38 | dbName := extension.DbName
39 | host := os.Getenv(extension.MysqlHostEnvVar)
40 | port := os.Getenv(extension.MysqlPortEnvVar)
41 | dbPoolConfigurations, err := resolvePoolingConfigurations(logger)
42 | if err != nil {
43 | logger.Debugf("No db connection pooling configurations found : %s", err)
44 | return nil, fmt.Errorf("failed to fetch db connection pooling configurations : %v", err)
45 | }
46 |
47 | conn := fmt.Sprint(dbUser, ":", dbPass, "@tcp(", host, ":", port, ")/"+dbName)
48 | logger.Debugf("Creating a new db connection pool: %v", conn)
49 |
50 | dbConnection, err := sql.Open(dbDriver, conn)
51 |
52 | if err != nil {
53 | return nil, fmt.Errorf("error occurred while establishing database connection pool "+
54 | " : %v", err)
55 | }
56 |
57 | dbConnection.SetMaxOpenConns(dbPoolConfigurations[extension.MaxIdleConnectionsEnvVar])
58 | dbConnection.SetMaxIdleConns(dbPoolConfigurations[extension.ConnectionMaxLifetimeEnvVar])
59 | dbConnection.SetConnMaxLifetime(time.Minute * time.Duration(dbPoolConfigurations[extension.
60 | ConnectionMaxLifetimeEnvVar]))
61 |
62 | err = dbConnection.Ping()
63 | if err != nil {
64 | return nil, fmt.Errorf("error occurred while pinging database connection pool "+
65 | " : %v", err)
66 | }
67 |
68 | logger.Debugf("Ping successful. DB connection pool established")
69 |
70 | return dbConnection, nil
71 | }
72 |
73 | func resolvePoolingConfigurations(logger *zap.SugaredLogger) (map[string]int, error) {
74 | m := make(map[string]int)
75 |
76 | maxOpenConnections, err := strconv.Atoi(os.Getenv(extension.MaxOpenConnectionsEnvVar))
77 | if err != nil {
78 | return nil, fmt.Errorf("error occurred while converting max open connections string into integer "+
79 | " : %v", err)
80 | }
81 | m[extension.MaxOpenConnectionsEnvVar] = maxOpenConnections
82 | maxIdleConnections, err := strconv.Atoi(os.Getenv(extension.MaxIdleConnectionsEnvVar))
83 | if err != nil {
84 | return nil, fmt.Errorf("error occurred while converting max idle connections string into integer "+
85 | " : %v", err)
86 | }
87 | m[extension.MaxIdleConnectionsEnvVar] = maxIdleConnections
88 | maxLifetime, err := strconv.Atoi(os.Getenv(extension.ConnectionMaxLifetimeEnvVar))
89 | if err != nil {
90 | return nil, fmt.Errorf("error occurred while converting max lifetime string into integer "+
91 | " : %v", err)
92 | }
93 | m[extension.ConnectionMaxLifetimeEnvVar] = maxLifetime
94 | logger.Debugf("Fetched db connection pooling configurations. MaxOpenConns = %d, "+
95 | "MaxIdleConns = %d, MaxLifetime = %d", maxOpenConnections, maxIdleConnections, maxLifetime)
96 |
97 | return m, nil
98 | }
99 |
--------------------------------------------------------------------------------
/components/api/docker_registry/registry.bal:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 WSO2, Inc. (http://wso2.com)
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License
16 | //
17 | // ------------------------------------------------------------------------
18 |
19 | import ballerina/config;
20 | import ballerina/http;
21 | import ballerina/io;
22 | import ballerina/log;
23 |
24 | public function getManifestDigest(string orgName, string imageName, string artifactVersion, string bearerToken)
25 | returns string | error {
26 | log:printDebug(io:sprintf("Invoking getManifest end point of registry API with a docker auth token. orgName: %s, "+
27 | "imageName: %s, artifactVersion: %s", orgName, imageName, artifactVersion));
28 | string getManifestEndPoint = io:sprintf("/v2/%s/%s/manifests/%s", orgName, imageName, artifactVersion);
29 | http:Client dockerRegistryClient = getOAuth2RegistryClient(bearerToken);
30 | var responseForGetManifest = dockerRegistryClient->get(getManifestEndPoint, message = "");
31 |
32 | if (responseForGetManifest is http:Response) {
33 | log:printDebug(io:sprintf("Received status code for getManifestDigest request: %d",
34 | responseForGetManifest.statusCode));
35 | if (responseForGetManifest.statusCode == http:OK_200) {
36 | log:printDebug(io:sprintf("Successfully retrieved the digest of the atifact \'%s/%s:%s\'. ", orgName,
37 | imageName, artifactVersion));
38 | return responseForGetManifest.getHeader(constants:REGISTRY_DIGEST_HEADER);
39 | } else {
40 | error er = error(io:sprintf("Failed to fetch the digest of docker manifest. This may be due to an unknown "+
41 | "manifest. Status Code : %s", responseForGetManifest.statusCode));
42 | return er;
43 | }
44 | } else {
45 | error er = error(io:sprintf("Error while fetching digest of docker manifest. %s", responseForGetManifest));
46 | return er;
47 | }
48 | }
49 |
50 | public function deleteManifest(string orgName, string imageName, string manifestdigest, string bearerToken)
51 | returns error? {
52 | log:printDebug(io:sprintf("Invoking deleteManifest end point of registry API with a docker auth token. orgName: %s, "+
53 | "imageName: %s, digest: %s", orgName, imageName, manifestdigest));
54 | http:Client dockerRegistryClient = getOAuth2RegistryClient(bearerToken);
55 | string deleteEndPoint = io:sprintf("/v2/%s/%s/manifests/%s", orgName, imageName, manifestdigest);
56 | var responseForDeleteManifest = dockerRegistryClient->delete(deleteEndPoint, "");
57 |
58 | if (responseForDeleteManifest is http:Response) {
59 | log:printDebug(io:sprintf("Received status code for deleteManifes request: %d",
60 | responseForDeleteManifest.statusCode));
61 | if (responseForDeleteManifest.statusCode == http:ACCEPTED_202) {
62 | log:printDebug(io:sprintf("Deleted the artifact \'%s/%s\'. Digest : %s", orgName, imageName,
63 | manifestdigest));
64 | } else {
65 | error er = error("Failed to delete the docker manifest. This may be due to an unknown manifest");
66 | return er;
67 | }
68 | } else {
69 | error er = error(io:sprintf("Error while deleting docker manifest. %s", responseForDeleteManifest));
70 | return er;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/components/portal/src/components/common/error/UnknownError.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | import Button from "@material-ui/core/Button/Button";
20 | import CelleryError from "../../../img/celleryError.jpg";
21 | import Home from "@material-ui/icons/Home";
22 | import React from "react";
23 | import {withRouter} from "react-router-dom";
24 | import {withStyles} from "@material-ui/core";
25 | import * as PropTypes from "prop-types";
26 |
27 | const styles = (theme) => ({
28 | unknownErrorContainer: {
29 | position: "relative",
30 | top: 0,
31 | left: 0,
32 | height: "100%",
33 | width: "100%",
34 | display: "grid"
35 | },
36 | unknownError: {
37 | margin: "auto",
38 | textAlign: "center"
39 | },
40 | unknownErrorImg: {
41 | marginTop: theme.spacing.unit * 5,
42 | height: 150
43 | },
44 | unknownErrorTitle: {
45 | margin: theme.spacing.unit,
46 | fontSize: "1.5em",
47 | fontWeight: 400,
48 | color: "#6e6e6e"
49 | },
50 | unknownErrorDescription: {
51 | fontSize: "1em",
52 | fontWeight: 300,
53 | color: "#808080",
54 | maxWidth: "50vw"
55 | },
56 | navigationButtonsContainer: {
57 | margin: theme.spacing.unit * 3
58 | },
59 | navigationButton: {
60 | margin: theme.spacing.unit
61 | },
62 | navigationButtonIcon: {
63 | marginRight: theme.spacing.unit
64 | }
65 | });
66 |
67 | const UnknownError = ({classes, title, description, showNavigationButtons}) => (
68 |
69 |
70 |
71 |
72 | {title ? title : "Something Went Wrong"}
73 |