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

feat: extract homepage and repository and description from fpm.toml #36

Merged
merged 75 commits into from
Jun 25, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
fc97933
feat: add APIs for email verification
henilp105 May 11, 2023
7a24e58
feat: add UI for email verification
henilp105 May 11, 2023
47079db
feat: add reducers and actions for email verification
henilp105 May 11, 2023
de8a8be
fix: redundant variable
henilp105 May 11, 2023
1093191
feat: add APIs for email change functionality
henilp105 May 11, 2023
d3b1b6e
feat: fix bugs
henilp105 May 11, 2023
815699c
fix: #34
henilp105 May 16, 2023
5ba8f05
add readme for the registry
henilp105 May 16, 2023
f904731
add: help and fix rreducers
henilp105 May 16, 2023
c96154a
fix: #35
henilp105 May 16, 2023
d6fa8e0
token duration
henilp105 May 16, 2023
0024731
add the read description and homepage and repository
henilp105 May 16, 2023
f4ddeb8
nfeat: update packages
henilp105 May 16, 2023
2cac330
add : css to help page
henilp105 May 16, 2023
2d8152f
Merge branch 'fortran-lang:main' into main
henilp105 May 16, 2023
7050da2
update: readme
henilp105 May 16, 2023
7a41c6b
Merge branch 'main' of https://github.com/henilp105/registry
henilp105 May 16, 2023
ed56575
fix: fix admin page bugs
henilp105 May 19, 2023
c26dfd5
fix: fix admin page bugs
henilp105 May 19, 2023
28a6dff
fix: fix admin page bugs
henilp105 May 19, 2023
6abb823
fix: only allow the packages and namespaces and tarballs for the clone
henilp105 May 19, 2023
7e14cb2
disable account transfer API
henilp105 May 19, 2023
6a7ebfa
admin navbar setting
henilp105 May 20, 2023
9ff37cf
Merge branch 'fortran-lang:main' into main
henilp105 May 21, 2023
b06456e
Merge branch 'fortran-lang:main' into main
henilp105 May 25, 2023
2e68e53
Merge branch 'main' into main
henilp105 Jun 2, 2023
91e7f0c
fix: bugs
henilp105 Jun 3, 2023
1d017a3
fix: verify email reducer
henilp105 Jun 3, 2023
9dd0ebf
feat: add dry run
henilp105 Jun 3, 2023
24d4827
feat: add support for zip and tarballs
henilp105 Jun 3, 2023
c0289a7
fix : #38
henilp105 Jun 3, 2023
0467b4c
fix: handle invalid package metadata
henilp105 Jun 3, 2023
84e6eb3
fix: help styling
henilp105 Jun 3, 2023
be244f4
fix: handle extraction of toml from tar and zip, fix dry run
henilp105 Jun 3, 2023
8fa5859
resolve merge conflicts
henilp105 Jun 3, 2023
6570868
Merge branch 'fortran-lang:main' into main
henilp105 Jun 7, 2023
b08f99a
fix: emails
henilp105 Jun 7, 2023
e3cfb32
Merge branch 'main' of https://github.com/henilp105/registry
henilp105 Jun 7, 2023
0765971
fix: email verification
henilp105 Jun 7, 2023
0cd68d9
fix: changes and buttons animation and add verification
henilp105 Jun 7, 2023
5167625
fix: auth reducers
henilp105 Jun 7, 2023
3123920
fix: auth
henilp105 Jun 7, 2023
ab9a265
feat: Support multiple tarballs format
henilp105 Jun 12, 2023
0270d0e
fix: account
henilp105 Jun 12, 2023
e8a1d3f
add: reducers and actions for email change
henilp105 Jun 12, 2023
4bbff42
update dependencies
henilp105 Jun 12, 2023
5f37ef4
fix: tarballs
henilp105 Jun 12, 2023
6dd7257
Merge branch 'main' into main
henilp105 Jun 12, 2023
7958909
fix: alt rendering
henilp105 Jun 12, 2023
25082b1
Merge branch 'main' of https://github.com/henilp105/registry
henilp105 Jun 12, 2023
4d5f787
fix: toml extraction
henilp105 Jun 13, 2023
715f4fa
fix: auth bug and namespace rendering
henilp105 Jun 13, 2023
bd162f4
restrict non verified emails
henilp105 Jun 13, 2023
78a4b2b
restrict non verified emails
henilp105 Jun 13, 2023
0aee1a4
restrict non verified emails fix API response
henilp105 Jun 13, 2023
af4da33
fix: verify email loader
henilp105 Jun 13, 2023
09ad559
feat: add archives UI
henilp105 Jun 13, 2023
59f45ad
feat: add reducers for archives
henilp105 Jun 13, 2023
158d19c
fix: add actions
henilp105 Jun 13, 2023
0cf64f3
fix: add archives UI
henilp105 Jun 13, 2023
2de3636
feat: add docs for mongodump
henilp105 Jun 13, 2023
8c12889
fix: docker and fpm
henilp105 Jun 14, 2023
fef1cd4
fix: docker file
henilp105 Jun 14, 2023
77d7e45
fix: APIs for package upload and docker validate
henilp105 Jun 14, 2023
3528f1c
fix: change email restrict
henilp105 Jun 14, 2023
96379d1
fix: auth
henilp105 Jun 15, 2023
277ff35
fix: auth
henilp105 Jun 15, 2023
40f4b9f
auth
henilp105 Jun 15, 2023
cae240a
fix: mail
henilp105 Jun 15, 2023
1263396
fix: reset password bug
henilp105 Jun 16, 2023
523f885
Merge branch 'main' into main
henilp105 Jun 22, 2023
ca865f1
fix: reset password auth
henilp105 Jun 22, 2023
64b679e
notify user
henilp105 Jun 23, 2023
dddedc5
fix: add loading and notification
henilp105 Jun 25, 2023
de439df
fix: login page
henilp105 Jun 25, 2023
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
31 changes: 23 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
# registry
Registry for Fortran package manager
# Registry for Fortran package manager

## Python Flask app with Nginx and Mongo database
Currently for the testing phase :
1. backend APIs are hosted at: http://registry-apis.vercel.app/
2. frontend is hosted at: https://registry-frontend.vercel.app/
3. Documentation for the APIs are available at: https://registry-apis.vercel.app/apidocs/

Project structure:
**Please note: the current registry is a playground: its database will be fully deleted once its functionality is established. Please do not use it for production yet! more information will follow then.**

The fpm release [0.8.2](https://fortran-lang.discourse.group/t/fpm-version-0-8-2-released-centralized-registry-playground/5792) introduces fpm support for uploading packages to the fpm-registry server directly from the command-line interface, via

```
fpm publish --token <token-here>
```

fpm will now interact with a web interface that will help to manage the namespaces & packages.


## fpm - registry : Python Flask app with Nginx and Mongo database

backend Project structure:
```
.
├── compose.yaml
Expand All @@ -20,7 +35,7 @@ Project structure:

```

## Deploy with docker compose
## Instructions for Deploy with docker compose

```
$ sudo chmod 666 /var/run/docker.sock (for root access)
Expand All @@ -38,9 +53,9 @@ Hello world, Mongo Flask
set MONGO_URI=MONGO_DB_ATLAS_URL (in .env file in flask directory)
The MONGO_URI must be set in the environment (or, alternatively, in the .env file in the flask directory) to the URL value of the MongoDB to use. For example,If deploying to production, MONGO_URI should be set to mongo container address.
set the following env variables in the .env file in the flask folder:
- SALT=MYSALT
- MONGO_URI
- MONGO_DB_NAME
- SALT
- MONGO_URI
- MONGO_DB_NAME
- SUDO_PASSWORD
- MONGO_USER_NAME
- MONGO_PASSWORD
Expand Down
76 changes: 75 additions & 1 deletion flask/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def signup():

if not registry_user:
db.users.insert_one(user)

# send_verify_email(email) #TODO: uncomment this line
henilp105 marked this conversation as resolved.
Show resolved Hide resolved
return (
jsonify(
{
Expand Down Expand Up @@ -266,3 +266,77 @@ def forgot_password(*email):
jsonify({"message": "Password reset link sent to your email", "code": 200}),
200,
)


def send_verify_email(email):

user = db.users.find_one({"email": email})

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

uuid = generate_uuid()
db.users.update_one({"email": email}, {"$set": {"uuid": uuid}})

message = f"""\n
Dear {user['username']},

We received a request to verify your email. To verify your email, please copy paste the link below in a new browser window:

{env_var['host']}/account/verify/{uuid}

Thank you,
The Fortran-lang Team"""

message = f'Subject: Verify email \nTo: {email}\n{message}'

# sending the mail
smtp.sendmail(to_addrs=email, msg=message, from_addr=fortran_email)

return (
jsonify({"message": "verification link sent to your email", "code": 200}),
200,
)

@app.route("/auth/verify-email", methods=["POST"])
def verify_email():
uuid = request.form.get("uuid")

if not uuid:
return jsonify({"message": "Unauthorized", "code": 401}), 401

user = db.users.find_one({"uuid": uuid})

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

return jsonify({"message": "Successfully Verified Email", "code": 200}), 200

@app.route("/auth/change-email", methods=["POST"])
def change_email():
uuid = request.form.get("uuid")
new_email = request.form.get("new_email")

if not uuid:
return jsonify({"message": "Unauthorized", "code": 401}), 401

user = db.users.find_one({"uuid": uuid})

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

if not new_email:
return jsonify({"message": "Please enter new email", "code": 400}), 400

used_email = db.users.find_one({"email": new_email})

if used_email:
return jsonify({"message": "Email already in use", "code": 400}), 400

db.users.update_one(
{"uuid": uuid},
{"$set": {"email": new_email}},
)
send_verify_email(new_email)

return jsonify({"message": "Email id Successfully changed", "code": 200}), 200
2 changes: 1 addition & 1 deletion flask/mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def generate_latest_tarball():
os.mkdir(backup_dir)

# Execute the mongodump command
command = f"mongodump --host {mongo_uri} --authenticationDatabase admin --username {mongo_username} --password {mongo_password} --db {database_name} --out {backup_dir}"
command = f"mongodump --host {mongo_uri} --authenticationDatabase admin --username {mongo_username} --password {mongo_password} --db {database_name} --collection namespaces --collection packages --collection tarballs --out {backup_dir}"
subprocess.call(command, shell=True)

# Create a tar archive of the backup directory
Expand Down
22 changes: 20 additions & 2 deletions flask/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from datetime import datetime, timedelta
from auth import generate_uuid
from app import swagger
import zipfile
import toml
from flasgger.utils import swag_from
from urllib.parse import unquote
import math
Expand Down Expand Up @@ -197,6 +199,10 @@ def upload():
file_object_id = file_storage.put(tarball, content_type="application/gzip", filename=tarball_name)



# Extract the package metadata from the tarball's fpm.toml file.
package_data = extract_fpm_toml(tarball_name)

# TODO: Uncomment this when the package validation is enabled

# validate the package
Expand All @@ -210,7 +216,9 @@ def upload():
package_obj = {
"name": package_name,
"namespace": namespace_doc["_id"],
"description": "Sample Test description",
"description": package_data["description"],
henilp105 marked this conversation as resolved.
Show resolved Hide resolved
"homepage": package_data["homepage"],
"repository": package_data["repository"],
"license": package_license,
"createdAt": datetime.utcnow(),
"updatedAt": datetime.utcnow(),
Expand Down Expand Up @@ -429,6 +437,8 @@ def get_package(namespace_name, package_name):
"name": package["name"],
"namespace": namespace["namespace"],
"description": package["description"],
"repository": package["repository"],
"homepage": package["homepage"],
"latest_version_data": {
"dependencies": package["versions"][-1]["dependencies"],
"version": package["versions"][-1]["version"],
Expand Down Expand Up @@ -672,4 +682,12 @@ def checkUserUnauthorizedForNamespaceTokenCreation(user_id, namespace_doc):
admins_id_list = [str(obj_id) for obj_id in namespace_doc["admins"]]
maintainers_id_list = [str(obj_id) for obj_id in namespace_doc["maintainers"]]
str_user_id = str(user_id)
return str_user_id not in admins_id_list and str_user_id not in maintainers_id_list
return str_user_id not in admins_id_list and str_user_id not in maintainers_id_list

def extract_fpm_toml(file_obj):
with zipfile.ZipFile(file_obj, 'r') as zip_ref:
zip_ref.extract("fpm.toml")
with open("fpm.toml", 'r') as file:
data = toml.load(file)

return data
1 change: 1 addition & 0 deletions flask/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ flasgger
license-expression
semantic-version
docker
toml
79 changes: 40 additions & 39 deletions flask/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,46 +213,47 @@ def admin():
)


@app.route("/users/admin/transfer", methods=["POST"])
@app.route("/users/admin/transfer", methods=["POST"]) # TODO: enable this functionality
def transfer_account():
uuid = request.form.get("uuid")
if not uuid:
return jsonify({"message": "Unauthorized", "code": 401}), 401
else:
user = db.users.find_one({"uuid": uuid})

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

if "admin" not in user["roles"]:
return jsonify({"message": "Unauthorized", "code": 401}), 401
else:
old_user = request.form.get("old_username")
new_user = request.form.get("new_username")
new_email = request.form.get("new_email")
db.users.update_one(
{"username": old_user},
{
"$set": {
"email": new_email,
"username": new_user,
"uuid": "",
"loggedCount": 0,
"loginAt": None,
"lastLogout": None,
}
},
)
forgot_password(new_email)
return (
jsonify(
{
"message": "Account Transfer Successful and Password reset request sent.",
"code": 200,
}
),
200,
)
return jsonify({"message": "This Functionality has been disabled.", "code": 501}), 501
# uuid = request.form.get("uuid")
# if not uuid:
# return jsonify({"message": "Unauthorized", "code": 401}), 401
# else:
# user = db.users.find_one({"uuid": uuid})

# if not user:
# return jsonify({"message": "User not found", "code": 404}), 404

# if "admin" not in user["roles"]:
# return jsonify({"message": "Unauthorized", "code": 401}), 401
# else:
# old_user = request.form.get("old_username")
# new_user = request.form.get("new_username")
# new_email = request.form.get("new_email")
# db.users.update_one(
# {"username": old_user},
# {
# "$set": {
# "email": new_email,
# "username": new_user,
# "uuid": "",
# "loggedCount": 0,
# "loginAt": None,
# "lastLogout": None,
# }
# },
# )
# forgot_password(new_email)
# return (
# jsonify(
# {
# "message": "Account Transfer Successful and Password reset request sent.",
# "code": 200,
# }
# ),
# 200,
# )


@app.route("/<username>/maintainer", methods=["POST"])
Expand Down
5 changes: 5 additions & 0 deletions registry/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import NoPage from "./pages/404";
import UserPage from "./pages/user";
import PackagePage from "./pages/package";
import NamespaceForm from "./pages/createNamespace";
import VerifyEmail from "./pages/verifyemail";
import NamespacePage from "./pages/namespace";
import AdminSection from "./pages/admin";
import ForgotPassword from "./pages/forgotpassword";
Expand All @@ -32,6 +33,10 @@ function App() {
path="/account/reset-password/:uuid"
element={<ResetPassword />}
/>
<Route
henilp105 marked this conversation as resolved.
Show resolved Hide resolved
path="/account/verify/:uuid"
element={<VerifyEmail />}
/>
<Route path="/account/register" element={<Register />} />
<Route path="/help" element={<Help />} />
<Route path="/search" element={<Search />} />
Expand Down
11 changes: 8 additions & 3 deletions registry/src/pages/Navbar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import Image from "react-bootstrap/Image";
Expand All @@ -8,6 +8,7 @@ import Navbar from "react-bootstrap/Navbar";
import NavDropdown from "react-bootstrap/NavDropdown";
import { logout } from "../store/actions/authActions";
import { searchPackage, setQuery } from "../store/actions/searchActions";
import { adminAuth } from "../store/actions/adminActions";

const NavbarComponent = () => {
const dispatch = useDispatch();
Expand All @@ -19,6 +20,10 @@ const NavbarComponent = () => {
const username = useSelector((state) => state.auth.username);
const uuid = useSelector((state) => state.auth.uuid);

useEffect(() => {
henilp105 marked this conversation as resolved.
Show resolved Hide resolved
dispatch(adminAuth(uuid));
}, [isAuthenticated, uuid]);

const signOut = () => {
dispatch(logout(uuid));
};
Expand Down Expand Up @@ -127,8 +132,8 @@ const SearchBar = () => {
}
};

const handleKeyDown = event => {
if (event.key === 'Enter') {
const handleKeyDown = (event) => {
if (event.key === "Enter") {
search();
}
};
Expand Down
Loading