Skip to content

Commit fa858ec

Browse files
k-avyGMishx
authored andcommitted
docs: added documentation and updated readme.md
1 parent 01f27fa commit fa858ec

File tree

8 files changed

+121
-5
lines changed

8 files changed

+121
-5
lines changed

README.md

+50-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,56 @@
44
-->
55
# LicenseDb
66

7-
This project aims to create a centralized OSS license database, to manage opensource
8-
licenses used by an organization. And different compliance tools like fossology,
9-
sw360 etc. can sync with licenseDB application to update its own license data.
7+
License as a service provides a convenient and effective way for organizations to
8+
manage their use of open-source licenses. With the growing popularity of open-source
9+
software, organizations are finding it more difficult to keep track of the various
10+
licenses and terms under which they are permitted to use open-source components.
11+
Open-source licenses can be complicated, making it difficult to understand how they
12+
apply to a specific piece of software or interact with other licenses. It can be
13+
used for various purposes by organizations and tools like [FOSSology](https://fossology.org)
14+
and [SW360](https://eclipse.org/sw360) like license identification, filtering, and
15+
managing licenses. There are benefits of this service such as increasing flexibility,
16+
a faster time-to-access, and managing the database.
17+
18+
## Database
19+
20+
Licensedb database has licenses, obligations, obligation map, users, their audits
21+
and changes.
22+
23+
- **license_dbs** table has list of licenses and all the data related to the licenses.
24+
- **obligations** table has the list of obligations that are related to the licenses.
25+
- **obligation_maps** table that maps obligations to their respective licenses.
26+
- **users** table has the user that are associated with the licenses.
27+
- **audits** table has the data of audits that are done in obligations or licenses
28+
- **change_logs** table has all the change history of a particular audit.
29+
30+
![alt text](./docs/assets/licensedb_erd.png)
31+
32+
### APIs
33+
34+
There are multiple API endpoints for licenses, obligations, user and audit
35+
endpoints.
36+
37+
### API endpoints
38+
39+
| # | Method | API Endpoints | Examples | Descriptions |
40+
| --- | --------- | ---------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------- |
41+
| 1 | **GET** | `/api/licenses/:shortname` | /api/licenses/MIT | Gets all data related to licenses by their shortname |
42+
| 2 | **GET** | `/api/licenses/` | /api/licenses/copyleft="t"&active="t" | Get filter the licenses as per the filters |
43+
| 3 | **POST** | `/api/licenses` | /api/licenses | Create a license with unique shortname |
44+
| 4 | **POST** | `/api/licenses/search` | /api/licenses/search | Get the licenses with the post request filtered by field, search term and type |
45+
| 5 | **PATCH** | `/api/licenses/:shortname` | /api/licenses/MIT | It updates the particular fields as requested of the license with shortname |
46+
| 6 | **GET** | `/api/users` | /api/users | Get all the users and their data |
47+
| 7 | **GET** | `/api/users/:id` | /api/users/1 | Get data relate to user by its id |
48+
| 8 | **POST** | `/api/users` | /api/users | Create a user with unique data |
49+
| 9 | **GET** | `/api/obligations` | /api/obligations | Get all the obligations |
50+
| 10 | **GET** | `/api/obligation/:topic` | /api/obligation/topic | Gets all data related to obligations by their topic |
51+
| 11 | **POST** | `/api/obligations` | /api/obligations | Create an obligation as well as add it to obligation map |
52+
| 12 | **PATCH** | `/api/obligations/:topic` | /api/obligations | It updates the particular fields as requested of the obligation with topic |
53+
| 13 | **GET** | `/api/audit` | /api/audit | Get the audit history of all the licenses and obligations |
54+
| 14 | **GET** | `/api/audit/:audit_id` | /api/audit/1 | Get the data of a particular audit by its id |
55+
| 15 | **GET** | `/api/audit/:audit_id/changes` | /api/audit/1/changes | Get the change logs of the particular audit id |
56+
| 16 | **GET** | `/api/audit/:audit_id/changes/:id` | /api/audit/1/changes/2 | Get a particular change log of the particular audit id |
1057

1158
## Prerequisite
1259

docs/assets/licensedb_erd.png

57.4 KB
Loading

pkg/api/api.go

+42
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func Router() *gin.Engine {
5353
return r
5454
}
5555

56+
// The HandleInvalidUrl function returns the error when an invalid url is entered
5657
func HandleInvalidUrl(c *gin.Context) {
5758

5859
er := models.LicenseError{
@@ -64,6 +65,8 @@ func HandleInvalidUrl(c *gin.Context) {
6465
}
6566
c.JSON(http.StatusNotFound, er)
6667
}
68+
69+
// The get all License function returns all the license data present in the database
6770
func GetAllLicense(c *gin.Context) {
6871

6972
var licenses []models.LicenseDB
@@ -91,6 +94,9 @@ func GetAllLicense(c *gin.Context) {
9194
c.JSON(http.StatusOK, res)
9295
}
9396

97+
// Get license functions return data of the particular license by its shortname.
98+
// It inputs the shortname as query parameter
99+
// It returns error ehen no such license exists
94100
func GetLicense(c *gin.Context) {
95101
var license models.LicenseDB
96102

@@ -124,6 +130,8 @@ func GetLicense(c *gin.Context) {
124130
c.JSON(http.StatusOK, res)
125131
}
126132

133+
// The Create License function creates license in the database and add the required data
134+
// It return the license if it already exists in the database
127135
func CreateLicense(c *gin.Context) {
128136
var input models.LicenseInput
129137

@@ -200,6 +208,9 @@ func CreateLicense(c *gin.Context) {
200208
c.JSON(http.StatusCreated, res)
201209
}
202210

211+
// The Update license functions updates the particular license with a particular shortname.
212+
// It also creates the audit and change logs of the updates
213+
// It returns the updated license
203214
func UpdateLicense(c *gin.Context) {
204215
var update models.LicenseDB
205216
var license models.LicenseDB
@@ -446,6 +457,8 @@ func UpdateLicense(c *gin.Context) {
446457

447458
}
448459

460+
// The filter licenses returns the licenses after passing through certain filters.
461+
// It takes the filters as query parameters and filters accordingly.
449462
func FilterLicense(c *gin.Context) {
450463
SpdxId := c.Query("spdxid")
451464
DetectorType := c.Query("detector_type")
@@ -523,6 +536,10 @@ func FilterLicense(c *gin.Context) {
523536

524537
}
525538

539+
// SearchInLicense searches for license data based on user-provided search criteria.
540+
// It accepts a JSON request body containing search parameters and responds with JSON
541+
// containing the matching license data or error messages if the search request is
542+
// invalid or if the search algorithm is not supported.
526543
func SearchInLicense(c *gin.Context) {
527544
var input models.SearchLicense
528545

@@ -570,6 +587,8 @@ func SearchInLicense(c *gin.Context) {
570587

571588
}
572589

590+
// GetAllAudit retrieves a list of all audit records from the database and responds with
591+
// JSON containing the audit data or an error message if the records are not found.
573592
func GetAllAudit(c *gin.Context) {
574593
var audit []models.Audit
575594

@@ -595,6 +614,8 @@ func GetAllAudit(c *gin.Context) {
595614
c.JSON(http.StatusOK, res)
596615
}
597616

617+
// GetAudit retrieves a specific audit record by its ID from the database and responds
618+
// with JSON containing the audit data or an error message if the record is not found.
598619
func GetAudit(c *gin.Context) {
599620
var chngelog models.Audit
600621
id := c.Param("audit_id")
@@ -620,6 +641,9 @@ func GetAudit(c *gin.Context) {
620641
c.JSON(http.StatusOK, res)
621642
}
622643

644+
// GetChangeLog retrieves a list of change history records associated with a specific
645+
// audit by its audit ID from the database and responds with JSON containing the change
646+
// history data or an error message if no records are found.
623647
func GetChangeLog(c *gin.Context) {
624648
var changelog []models.ChangeLog
625649
id := c.Param("audit_id")
@@ -646,6 +670,9 @@ func GetChangeLog(c *gin.Context) {
646670
c.JSON(http.StatusOK, res)
647671
}
648672

673+
// GetChangeLogbyId retrieves a specific change history record by its ID for a given audit.
674+
// It responds with JSON containing the change history data or error messages if the record
675+
// is not found or if it does not belong to the specified audit.
649676
func GetChangeLogbyId(c *gin.Context) {
650677
var changelog models.ChangeLog
651678
auditid := c.Param("audit_id")
@@ -682,6 +709,10 @@ func GetChangeLogbyId(c *gin.Context) {
682709
c.JSON(http.StatusOK, res)
683710
}
684711

712+
// CreateObligation creates a new obligation record based on the provided input JSON data.
713+
// It performs validation, generates an MD5 hash of the obligation text, and associates
714+
// the obligation with relevant licenses. The function responds with JSON containing the
715+
// newly created obligation data or error messages in case of validation or database errors.
685716
func CreateObligation(c *gin.Context) {
686717
var input models.ObligationInput
687718

@@ -764,6 +795,8 @@ func CreateObligation(c *gin.Context) {
764795
c.JSON(http.StatusCreated, res)
765796
}
766797

798+
// GetAllObligation retrieves a list of all active obligation records from the database and
799+
// responds with JSON containing the obligation data or an error message if no records are found.
767800
func GetAllObligation(c *gin.Context) {
768801
var obligations []models.Obligation
769802
query := db.DB.Model(&obligations)
@@ -791,6 +824,10 @@ func GetAllObligation(c *gin.Context) {
791824
c.JSON(http.StatusOK, res)
792825
}
793826

827+
// UpdateObligation updates an existing active obligation record based on the provided input JSON data.
828+
// It performs validation, updates the specified fields, and records changes in the audit log.
829+
// The function responds with JSON containing the updated obligation data or error messages in case
830+
// of validation or database errors.
794831
func UpdateObligation(c *gin.Context) {
795832
var update models.UpdateObligation
796833
var oldobligation models.Obligation
@@ -948,6 +985,8 @@ func UpdateObligation(c *gin.Context) {
948985
c.JSON(http.StatusOK, res)
949986
}
950987

988+
// DeleteObligation marks an existing obligation record as inactive based on the provided topic parameter.
989+
// It responds with an error message if the obligation is not found or if the deactivation operation fails.
951990
func DeleteObligation(c *gin.Context) {
952991
var obligation models.Obligation
953992
tp := c.Param("topic")
@@ -965,6 +1004,9 @@ func DeleteObligation(c *gin.Context) {
9651004
obligation.Active = false
9661005
}
9671006

1007+
// GetObligation retrieves an active obligation record based on the provided topic parameter.
1008+
// It responds with JSON containing the obligation data or an error message if the obligation
1009+
// is not found or if there is an error during retrieval.
9681010
func GetObligation(c *gin.Context) {
9691011
var obligation models.Obligation
9701012
query := db.DB.Model(&obligation)

pkg/api/api_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import (
1919
"github.com/stretchr/testify/assert"
2020
)
2121

22+
// TestMain is the main testing function for the application. It sets up the testing environment,
23+
// including configuring the Gin web framework for testing, connecting to a database,
24+
// running the tests, and exiting with the appropriate exit code.
2225
func TestMain(m *testing.M) {
2326
gin.SetMode(gin.TestMode)
2427
dbname := "fossology"
@@ -32,6 +35,7 @@ func TestMain(m *testing.M) {
3235
os.Exit(exitcode)
3336
}
3437

38+
// makeRequest is a utility function for creating and sending HTTP requests during testing.
3539
func makeRequest(method, path string, body interface{}, isAuthanticated bool) *httptest.ResponseRecorder {
3640
reqBody, _ := json.Marshal(body)
3741
req := httptest.NewRequest(method, path, bytes.NewBuffer(reqBody))

pkg/auth/auth.go

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/gin-gonic/gin"
1616
)
1717

18+
// CreateUser creates a new user based on the provided JSON request data.
1819
func CreateUser(c *gin.Context) {
1920
var user models.User
2021
if err := c.ShouldBindJSON(&user); err != nil {
@@ -52,6 +53,7 @@ func CreateUser(c *gin.Context) {
5253
c.JSON(http.StatusCreated, res)
5354
}
5455

56+
// GetAllUser retrieves a list of all users from the database.
5557
func GetAllUser(c *gin.Context) {
5658
var users []models.User
5759

@@ -76,6 +78,7 @@ func GetAllUser(c *gin.Context) {
7678
c.JSON(http.StatusOK, res)
7779
}
7880

81+
// GetUser retrieves a user by their user ID from the database.
7982
func GetUser(c *gin.Context) {
8083
var user models.User
8184
id := c.Param("id")
@@ -101,6 +104,7 @@ func GetUser(c *gin.Context) {
101104
c.JSON(http.StatusOK, res)
102105
}
103106

107+
// AuthenticationMiddleware is a middleware function for user authentication.
104108
func AuthenticationMiddleware() gin.HandlerFunc {
105109
return func(c *gin.Context) {
106110
authHeader := c.GetHeader("Authorization")

pkg/db/db.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ import (
1515
"gorm.io/gorm"
1616
)
1717

18+
// DB is a global variable to store the GORM database connection.
1819
var DB *gorm.DB
1920

21+
// Connect establishes a connection to the database using the provided parameters.
2022
func Connect(dbhost, port, user, dbname, password *string) {
2123

2224
dburi := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s", *dbhost, *port, *user, *dbname, *password)
@@ -29,12 +31,13 @@ func Connect(dbhost, port, user, dbname, password *string) {
2931
DB = database
3032
}
3133

34+
// Populatedb populates the database with license data from a JSON file if 'populatedb' is true.
3235
func Populatedb(populatedb bool, datafile string) {
3336
if populatedb {
3437
var licenses []models.LicenseJson
35-
// read the file of data
38+
// Read the content of the data file.
3639
byteResult, _ := ioutil.ReadFile(datafile)
37-
// unmarshal the json file and it into the struct format
40+
// Unmarshal the JSON file data into a slice of LicenseJson structs.
3841
if err := json.Unmarshal(byteResult, &licenses); err != nil {
3942
log.Fatalf("error reading from json file: %v", err)
4043
}

pkg/models/types.go

+11
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,15 @@ type UserResponse struct {
124124
Meta PaginationMeta `json:"paginationmeta"`
125125
}
126126

127+
// SearchLicense struct represents the input needed to search in a license.
127128
type SearchLicense struct {
128129
Field string `json:"field" binding:"required"`
129130
SearchTerm string `json:"search_term" binding:"required"`
130131
Search string `json:"search"`
131132
}
132133

134+
// Audit struct represents an audit entity with certain attributes and properties
135+
// It has user id as a foreign key
133136
type Audit struct {
134137
Id int `json:"id" gorm:"primary_key"`
135138
UserId int64 `json:"user_id"`
@@ -139,6 +142,7 @@ type Audit struct {
139142
Type string `json:"type"`
140143
}
141144

145+
// ChangeLog struct represents a change entity with certain attributes and properties
142146
type ChangeLog struct {
143147
Id int `json:"id" gorm:"primary_key"`
144148
Field string `json:"field"`
@@ -148,18 +152,21 @@ type ChangeLog struct {
148152
Audit Audit `gorm:"foreignKey:AuditId;references:Id" json:"-"`
149153
}
150154

155+
// ChangeLogResponse represents the design of API response of change log
151156
type ChangeLogResponse struct {
152157
Status int `json:"status"`
153158
Data []ChangeLog `json:"data"`
154159
Meta PaginationMeta `json:"paginationmeta"`
155160
}
156161

162+
// AuditResponse represents the response format for audit data.
157163
type AuditResponse struct {
158164
Status int `json:"status"`
159165
Data []Audit `json:"data"`
160166
Meta PaginationMeta `json:"paginationmeta"`
161167
}
162168

169+
// Obligation represents an obligation record in the database.
163170
type Obligation struct {
164171
Id int64 `json:"id" gorm:"primary_key"`
165172
Topic string `json:"topic"`
@@ -173,6 +180,7 @@ type Obligation struct {
173180
Md5 string `json:"md5" gorm:"unique"`
174181
}
175182

183+
// ObligationInput represents the input format for creating a new obligation.
176184
type ObligationInput struct {
177185
Topic string `json:"topic" binding:"required"`
178186
Type string `json:"type" binding:"required"`
@@ -185,6 +193,7 @@ type ObligationInput struct {
185193
Shortnames []string `json:"shortnames"`
186194
}
187195

196+
// UpdateObligation represents the input format for updating an existing obligation.
188197
type UpdateObligation struct {
189198
Topic string `json:"topic"`
190199
Type string `json:"type"`
@@ -197,6 +206,7 @@ type UpdateObligation struct {
197206
Md5 string `json:"md5"`
198207
}
199208

209+
// ObligationMap represents the mapping between an obligation and a license.
200210
type ObligationMap struct {
201211
ObligationPk int64 `json:"obligation_pk"`
202212
Obligation Obligation `gorm:"foreignKey:ObligationPk;references:Id" json:"-"`
@@ -205,6 +215,7 @@ type ObligationMap struct {
205215
LicenseDB LicenseDB `gorm:"foreignKey:RfPk;references:Id" json:"-"`
206216
}
207217

218+
// ObligationResponse represents the response format for obligation data.
208219
type ObligationResponse struct {
209220
Status int `json:"status"`
210221
Data []Obligation `json:"data"`

pkg/utils/util.go

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ package utils
55

66
import "github.com/fossology/LicenseDb/pkg/models"
77

8+
// The Converter function takes an input of type models.LicenseJson and converts it into a
9+
// corresponding models.LicenseDB object.
10+
// It performs several field assignments and transformations to create the LicenseDB object,
11+
// including generating the SpdxId based on the SpdxCompatible field.
12+
// The resulting LicenseDB object is returned as the output of this function.
813
func Converter(input models.LicenseJson) models.LicenseDB {
914
if input.SpdxCompatible == "t" {
1015
input.SpdxCompatible = input.Shortname

0 commit comments

Comments
 (0)