feat: create admin if it doesn't exists

This commit is contained in:
Leandro Antônio Farias Machado 2023-07-31 11:07:53 -03:00
parent ece09d5028
commit aab83ce587
3 changed files with 106 additions and 11 deletions

View File

@ -2,6 +2,13 @@ package api
import (
"encoding/json"
"log"
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/gorilla/mux"
"github.com/leandrofars/oktopus/internal/api/auth"
"github.com/leandrofars/oktopus/internal/api/cors"
@ -12,12 +19,6 @@ import (
"github.com/leandrofars/oktopus/internal/utils"
"go.mongodb.org/mongo-driver/mongo"
"google.golang.org/protobuf/proto"
"log"
"net/http"
"strconv"
"strings"
"sync"
"time"
)
type Api struct {
@ -65,9 +66,8 @@ func StartApi(a Api) {
authentication := r.PathPrefix("/api/auth").Subrouter()
authentication.HandleFunc("/login", a.generateToken).Methods("PUT")
authentication.HandleFunc("/register", a.registerUser).Methods("POST")
// Keep the line above commented to avoid people get unintended admin privileges.
// Uncomment it only once for you to get admin privileges and create new users.
//authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST")
authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST")
authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET")
iot := r.PathPrefix("/api/device").Subrouter()
iot.HandleFunc("", a.retrieveDevices).Methods("GET")
iot.HandleFunc("/{sn}/get", a.deviceGetMsg).Methods("PUT")
@ -757,6 +757,20 @@ func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
return
}
users, err := a.Db.FindAllUsers()
if err != nil {
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
adminExists := adminUserExists(users)
if adminExists {
log.Println("There might exist only one admin")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode("There might exist only one admin")
return
}
user.Level = AdminUser
if err := user.HashPassword(user.Password); err != nil {
@ -770,6 +784,29 @@ func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
}
}
func adminUserExists(users []map[string]interface{}) bool {
for _, x := range users {
if x["level"].(int32) == AdminUser {
log.Println("Admin exists")
return true
}
}
return false
}
func (a *Api) adminUserExists(w http.ResponseWriter, r *http.Request) {
users, err := a.Db.FindAllUsers()
if err != nil {
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
adminExits := adminUserExists(users)
json.NewEncoder(w).Encode(adminExits)
return
}
type TokenRequest struct {
Email string `json:"email"`
Password string `json:"password"`

View File

@ -1,5 +1,6 @@
import { createContext, useContext, useEffect, useReducer, useRef } from 'react';
import PropTypes from 'prop-types';
import { useRouter } from 'next/router';
const HANDLERS = {
INITIALIZE: 'INITIALIZE',
@ -63,6 +64,7 @@ export const AuthProvider = (props) => {
const { children } = props;
const [state, dispatch] = useReducer(reducer, initialState);
const initialized = useRef(false);
const router = useRouter();
const initialize = async () => {
// Prevent from calling twice in development mode with React.StrictMode enabled
@ -177,7 +179,31 @@ export const AuthProvider = (props) => {
};
const signUp = async (email, name, password) => {
throw new Error('Sign up is not implemented');
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"email": email,
"password": password,
"name": name
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENPOINT+"/auth/admin/register", requestOptions)
if (result.status == 200) {
router.push("/auth/login")
}else{
const content = await result.json()
throw new Error(content);
}
};
const signOut = () => {

View File

@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import Head from 'next/head';
import NextLink from 'next/link';
import { useRouter } from 'next/navigation';
@ -67,6 +67,38 @@ const Page = () => {
[auth, router]
);
const [adminExists, setAdminExists] = useState(true)
const initialize = async () => {
await adminUserExists()
}
const adminUserExists = async () => {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow',
};
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENPOINT}/auth/admin/exists`, requestOptions))
let content = await result.json()
console.log("content: ", content)
if (result.status != 200) {
throw new Error(content);
}else{
if (!content){
router.push("/auth/register")
}
}
}
useEffect(()=>{
initialize()
},[])
return (
<>
<Head>