Skip to content

Commit

Permalink
"chown" command for webdav
Browse files Browse the repository at this point in the history
  • Loading branch information
sidoruka committed Aug 23, 2023
1 parent c84e50f commit 6444781
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 1 deletion.
1 change: 1 addition & 0 deletions deploy/contents/install/install-config
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ CP_SHARE_SRV_STATIC_DIR=/opt/share-srv/static
# cp-dav
CP_DAV_INTERNAL_HOST=cp-dav.default.svc.cluster.local
CP_DAV_INTERNAL_PORT=31085
CP_DAV_EXTRA_INTERNAL_PORT=31086
CP_DAV_URL_PATH=webdav
CP_DAV_AUTH_URL_PATH=webdav/auth-sso
CP_DAV_SERVE_DIR=/dav-serve
Expand Down
6 changes: 6 additions & 0 deletions deploy/contents/k8s/cp-dav/cp-dav-dpl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ spec:
- name: cp-region-creds
mountPath: "/root/.cloud/regioncreds"
readOnly: true
- mountPath: /opt/api/pki
name: api-pki
readOnly: true
livenessProbe:
exec:
command:
Expand All @@ -52,6 +55,9 @@ spec:
- name: dav-logs
hostPath:
path: /opt/dav/logs
- name: api-pki
hostPath:
path: /opt/api/pki
- name: cp-region-creds
secret:
secretName: cp-region-creds-secret
Expand Down
4 changes: 4 additions & 0 deletions deploy/contents/k8s/cp-dav/cp-dav-svc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ spec:
port: ${CP_DAV_INTERNAL_PORT}
targetPort: ${CP_DAV_INTERNAL_PORT}
name: cp-dav-port-http
- protocol: TCP
port: ${CP_DAV_EXTRA_INTERNAL_PORT}
targetPort: ${CP_DAV_EXTRA_INTERNAL_PORT}
name: cp-dav-extra-port-http
selector:
cloud-pipeline/cp-dav: "true"
5 changes: 5 additions & 0 deletions deploy/docker/cp-dav/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ COPY sync/nfs-watcher.sh ${SYNC_HOME}/
# E.g.: cp cp ../../../scripts/nfs-roles-management ./ -r && docker build ...
COPY nfs-roles-management ${SYNC_HOME}/nfs-roles-management

# Extras
ENV EXTRA_HOME=/opt/dav-extra
RUN pip install PyJWT==1.6.1 cryptography==2.6.1 flask==1.1.4
COPY extra ${EXTRA_HOME}

ADD liveness.sh /liveness.sh
RUN chmod +x /liveness.sh

Expand Down
124 changes: 124 additions & 0 deletions deploy/docker/cp-dav/extra/dav-extra-command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/bin/bash

# Copyright 2017-2023 EPAM Systems, Inc. (https://www.epam.com/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import jwt
import flask
from flask import Flask, jsonify
import os

app = Flask(__name__)

def success(payload):
return jsonify({
"payload": payload,
"status": "OK"
})


def error(message):
return jsonify({
"message": message,
"status": "ERROR"
})

def get_path(username, path):
return os.path.join(os.getenv("CP_DAV_SERVE_DIR", "/dav-serve"), username, path)

def get_and_normalize_pub_key():
read_pub_key = open(
os.path.join(os.getenv("CP_API_SRV_CERT_DIR", "/opt/api/pki"), "jwt.key.public")
).read().strip()
if "BEGIN PUBLIC KEY" not in read_pub_key:
return "-----BEGIN PUBLIC KEY-----\n" \
+ read_pub_key \
+ "\n-----END PUBLIC KEY-----"
else:
return read_pub_key

def verify_token():
token = flask.request.cookies.get('bearer', None)
if not token:
auth_header = flask.request.headers.get('Authorization', None)

if not token:
raise RuntimeError('No cookie or authorization header is set')

token = token.replace("Bearer ", "")
payload = jwt.decode(
token,
get_and_normalize_pub_key(),
algorithms=["RS512"]
)

sub = payload['sub'].upper() if 'sub' in payload else None
if not sub:
raise RuntimeError('No user name is set in the token')

user_id = int(payload['user_id']) if 'user_id' in payload else None
if not user_id:
raise RuntimeError('No user id is set in the token')

uid_seed = int(os.getenv('CP_CAP_UID_SEED', 70000))

return user_id, sub, uid_seed + user_id

@app.route('/chown/', methods=['POST'])
def chown():
try:
user_id, sub, uid = verify_token()
flask_json = flask.request.json

if not flask_json:
return error('Request is empty')

if not 'path' in flask_json:
return error('Path is not provided')
path = flask_json['path']

paths_list = []
if isinstance(path, list):
paths_list = path
else:
paths_list.append(path)

if len(paths_list) == 0:
return error('Paths length is 0')

errors_list = []
for path_item in paths_list:
full_path = get_path(sub, path_item)
if not os.path.exists(full_path):
errors_list.append('Path {} does not exist'.format(full_path))
continue

gid = int(os.getenv('CP_DAV_MOUNT_DEFAULT_OWNER_GROUP', uid))
try:
os.chown(full_path, uid, gid)
except Exception as file_e:
errors_list.append('Path {} chown errored: {}'.format(full_path, file_e.__str__()))

if len(errors_list) == 0:
return success("{}:{} is set for:\n{}".format(uid, gid, '\n'.join(paths_list)))
else:
return error('\n'.join(errors_list))

except Exception as e:
return error(e.__str__())


if __name__ == '__main__':
dav_extra_port = int(os.getenv("CP_DAV_EXTRA_INTERNAL_PORT", 31086))
app.run(host='0.0.0.0', port=dav_extra_port)
3 changes: 3 additions & 0 deletions deploy/docker/cp-dav/init
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ rm -f /tmp/sync
# Start cron
crond

# Start the extra commands service
nohup python2 ${EXTRA_HOME}/dav-extra-command.py &> /dev/null &

# Update the Apache WebDAV configuration according to the environment variables
envsubst < /tmp/httpd.conf > ${APACHE_HOME}/conf/httpd.conf
envsubst < /tmp/webdav.conf > ${APACHE_HOME}/conf/extra/webdav.conf
Expand Down
3 changes: 2 additions & 1 deletion deploy/docker/cp-edge/init
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export CP_PREF_STORAGE_FSBROWSER_PORT="${CP_PREF_STORAGE_FSBROWSER_PORT:-8091}"
export CP_DAV_URL_PATH="${CP_DAV_URL_PATH:-webdav}"
export CP_DAV_INTERNAL_HOST="${CP_DAV_INTERNAL_HOST:-127.0.0.1}"
export CP_DAV_INTERNAL_PORT="${CP_DAV_INTERNAL_PORT:-31085}"
export CP_DAV_EXTRA_INTERNAL_PORT="${CP_DAV_EXTRA_INTERNAL_PORT:-31086}"
export CP_DAV_AUTH_URL_PATH="${CP_DAV_AUTH_URL_PATH:-webdav/auth-sso}"
export CP_DAV_EXTERNAL_MAPPING_URL="${CP_DAV_EXTERNAL_MAPPING_URL:-$EDGE_EXTERNAL_SCHEMA://$CP_EDGE_EXTERNAL_HOST:$CP_EDGE_EXTERNAL_PORT/$CP_DAV_URL_PATH/}"
export CP_PREF_UI_PIPELINE_DEPLOYMENT_NAME="${CP_PREF_UI_PIPELINE_DEPLOYMENT_NAME:-CloudPipeline}"
Expand Down Expand Up @@ -110,7 +111,7 @@ echo "$AUTH_HTML" > /etc/nginx/dav/webdav/auth-sso/index.html
NGINX_COMMON_CONF="$(envsubst '${CP_EDGE_SSL_PROTOCOLS} ${CP_EDGE_SSL_CIPHERS}' < /etc/nginx/endpoints-config/server.common.conf)"
echo "$NGINX_COMMON_CONF" > /etc/nginx/endpoints-config/server.common.conf

NGINX_CONF="$(envsubst '${CP_EDGE_REGION} ${CP_EDGE_CONNECT_PROXY_AUTHENTICATION} ${CP_EDGE_ROOT_PROXY_PASS_DESTINATION} ${CP_EDGE_INVALIDATE_AUTH_PATH} ${CP_EDGE_INVALIDATE_URL_CORS} ${CP_EDGE_FSBROWSER_CORS} ${CP_EDGE_WEB_CLIENT_MAX_SIZE} ${CP_DAV_URL_PATH} ${CP_DAV_INTERNAL_HOST} ${CP_DAV_INTERNAL_PORT} ${CP_DAV_AUTH_URL_PATH} ${EDGE_EXTERNAL_SCHEMA} ${CP_EDGE_CLUSTER_RESOLVER} ${CP_EDGE_CLUSTER_RESOLVER_TIMEOUT_SEC} ${CP_PREF_STORAGE_FSBROWSER_PORT}' < /etc/nginx/nginx.conf)"
NGINX_CONF="$(envsubst '${CP_EDGE_REGION} ${CP_EDGE_CONNECT_PROXY_AUTHENTICATION} ${CP_EDGE_ROOT_PROXY_PASS_DESTINATION} ${CP_EDGE_INVALIDATE_AUTH_PATH} ${CP_EDGE_INVALIDATE_URL_CORS} ${CP_EDGE_FSBROWSER_CORS} ${CP_EDGE_WEB_CLIENT_MAX_SIZE} ${CP_DAV_URL_PATH} ${CP_DAV_INTERNAL_HOST} ${CP_DAV_INTERNAL_PORT} ${CP_DAV_AUTH_URL_PATH} ${EDGE_EXTERNAL_SCHEMA} ${CP_EDGE_CLUSTER_RESOLVER} ${CP_EDGE_CLUSTER_RESOLVER_TIMEOUT_SEC} ${CP_PREF_STORAGE_FSBROWSER_PORT} ${CP_DAV_EXTRA_INTERNAL_PORT}' < /etc/nginx/nginx.conf)"
echo "$NGINX_CONF" > /etc/nginx/nginx.conf

# Add the "ingress" configuration to the nginx, which will force all the client traffic to flow via EDGE
Expand Down
9 changes: 9 additions & 0 deletions deploy/docker/cp-edge/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,15 @@ http {
access_by_lua_file /etc/nginx/create_cookie_dav.lua;
root /etc/nginx/dav;
}

location ~ ^/${CP_DAV_AUTH_URL_PATH}/extra/(.*) {
default_type text/html;
access_by_lua_file /etc/nginx/validate_cookie_ssh.lua;
resolver ${CP_EDGE_CLUSTER_RESOLVER} valid=${CP_EDGE_CLUSTER_RESOLVER_TIMEOUT_SEC}s ipv6=off;
set $cp_dav_backend "http://${CP_DAV_INTERNAL_HOST}:${CP_DAV_EXTRA_INTERNAL_PORT}/$1/";
proxy_pass $cp_dav_backend;
client_max_body_size 0;
}
}

server {
Expand Down

0 comments on commit 6444781

Please sign in to comment.